-
-
[分享]文件逻辑组织、物理组织和存储空间管理
-
发表于: 2小时前 6
-
AI模型:Deepseek
仅供参考
Let's Go!
=======================我是分割线=================================
文件的逻辑结构:
1. 无结构的字符流文件
Windows 文件系统(NTFS、FAT)把文件看作一串字节/字符,不划分记录。
例子:C:\test.txt、.log 日志、.bat 批处理文件。记事本按字符流读写,系统不关心内容分成几条记录。
2. 有结构的记录文件
由应用程序在字节流之上定义记录,常用记录式结构如下:
1. 连续结构:把记录按生成的先后顺序排列。
例子:Windows 事件日志 .evtx,事件记录按发生时间先后依次追加写入,先发生的事件在前,后发生的在后。
2. 多重结构:把记录按键和记录名排列成行列式结构。
例子:CSV 文件或 Excel 表格,每行是一条记录,每列是一个字段(记录名),键可以是第一列。如通讯录:姓名、电话、邮箱,每行一个联系人,键为姓名。
3. 转置结构:把含有相同键的记录指针全部指向该键。
例子:NTFS 的目录索引 $I30,以文件名为键,每个文件名对应一个文件记录指针;或数据库索引,将相同键值的记录指针集中存放,通过键快速定位多条记录。
4. 顺序结构:把文件中的键按规定的顺序排列。
例子:NTFS 的 B+ 树目录索引,文件名按键的字母顺序排列;或排序后的 CSV 文件,如按姓名拼音排序的通讯录。
总结:Windows 文件系统通常把文件视为无结构字节流;有结构记录文件是应用层解释出来的。逻辑结构取决于谁在读:记事本看是字符流,Excel 看是记录,数据库看是页和行,NTFS 看 $MFT 是文件记录数组。
常用存取方法:
在 Windows 文件系统(NTFS、FAT)中,文件本身通常被看作字节流,所以它直接支持顺序存取和随机存取;而按键存取通常要借助索引、目录或数据库来实现。
1. 顺序存取法
从文件开头开始,一个字节或一条记录接一条地往下读,不能跳过。
Windows 例子:
- 记事本打开 C:\test.txt,从第一行读到末尾。
- 命令行执行 type C:\Windows\WindowsUpdate.log,按顺序显示日志。
- 复制文件时,系统从源文件头顺序读到尾。
2. 随机存取法
可以直接跳到文件任意位置读写,不必从头开始。
Windows 例子:
- 程序用 SetFilePointer 跳到 .exe 文件的某个偏移,读取 PE 头或节表。
- 视频播放器拖动进度条,直接跳到视频文件的某个时间点读取数据。
- 数据库按页号读写 .mdf 文件中的某一页,而不是从头读。
3. 按键存取法
按记录的键(关键字/标识)查找记录,而不是按位置。Windows 文件系统本身不直接提供,但可通过索引或数据库实现。
Windows 例子:
- NTFS 目录索引 $I30 以文件名为键。你输入 C:\Windows\notepad.exe,NTFS 按文件名键快速找到对应文件记录。
- 注册表以键路径为键。程序访问 HKEY_CURRENT_USER\Software\Microsoft\Windows,就是按路径键查找对应键值。
- SQL Server 或 Access 按主键查找记录,如按学号查学生信息,底层用 B+ 树索引实现按键存取。
总结:
Windows 文件系统直接支持顺序存取和随机存取;按键存取通常建立在 NTFS 索引、注册表或数据库索引之上。
=======================我是分割线=================================
文件的物理结构:
在 Windows 系统中,文件物理结构可以通过 NTFS 和 FAT 文件系统来举例说明:
1. 连续文件
把一个在逻辑上连续的文件信息依次存放到物理块中。
Windows 例子:在 NTFS 分区上,经过磁盘碎片整理后,一个大文件(如虚拟机磁盘 C:\VM\Win10.vhdx)可能被分配到一段连续的磁盘簇中。此时 NTFS 的文件记录中,数据运行列表只需记录“起始簇号 + 连续长度”,系统按顺序读取即可。
2. 串联文件
非连续物理块存放文件信息,物理块没有顺序关系,每个物理块设有一个指针,指向下一个物理块的地址,所有物理块链接成队列。
Windows 例子:在 FAT32 格式的 U 盘上,一个碎片化的文件(如 D:\movie.mp4)被分散存放在多个不连续的簇中。FAT 表(文件分配表)记录了每个簇的下一个簇号,形成链表。系统读取时,先找到起始簇,再沿 FAT 表逐簇跳转,直到文件结束。
3. 索引文件
为每个文件建立一张索引表,索引表每一表项指出文件信息所在的逻辑块号和与之对应的物理块号。
Windows 例子:NTFS 分区上的文件(如 C:\Windows\System32\notepad.exe),其文件记录存放在主文件表 $MFT 中。数据属性包含一个“运行列表”(Data Runs),它相当于索引表,记录了逻辑簇号到物理簇号的映射。系统通过这张索引表直接定位文件的各个数据块,无需顺序扫描。
=======================我是分割线=================================
存储空间管理:
存储空间管理方法举例:
1. 空闲表法
用一张表记录每个连续空闲区的起始块号和长度。
例子:早期连续分配文件系统(如 IBM OS/360、CP/M)使用空闲表。
假设磁盘块 0~99,空闲表为:
- (10, 5):块 10~14 空闲
- (20, 8):块 20~27 空闲
- (50, 10):块 50~59 空闲
分配时从表中找合适长度的连续空闲区。
2. 空闲链表法
把所有空闲块链接成链表,每个空闲块中存放指向下一个空闲块的指针。
例子:早期 UNIX 文件系统、MINIX 文件系统。
空闲块链:1 → 5 → 8 → 12 → … → 结束。
分配时从链头取一块,释放时把块插回链表。也可把连续空闲区组成“空闲盘区链”。
3. 位图法
用二进制位表示每个磁盘块是否空闲,0 表示空闲,1 表示占用。
例子:
- NTFS:用 $Bitmap 文件记录簇的分配情况。
- Linux ext2/ext3/ext4:用块位图管理空闲块。
例如某段位图:00111000 表示第 2、3、4 块被占用,第 0、1、5、6、7 块空闲。新建文件时查 0 位,置 1;删除文件时置 0。
4. 成组链接法
把空闲块分成若干组,每组第一块记录下一组的块号和本组空闲块数。
例子:UNIX System V 的空闲块管理。
超级块中存放第一组空闲块信息;第一组最后一块指向第二组;第二组最后一块指向第三组……
分配时从当前组取块,取完一组后,根据指针读入下一组继续分配;释放时按组回收。
总结:
- 空闲表法适合连续分配,但易产生外部碎片。
- 空闲链表法实现简单,但查找效率低。
- 位图法直观高效,现代文件系统(NTFS、ext4)常用。
- 成组链接法是 UNIX 经典方法,适合大量空闲块的管理。
冰与火的战歌:Windows内核攻防实战高级班!从零到实战,融合AI与Windows内核攻防全技术栈,打造具备自动化能力的内核开发高手。