创建类似 FAT 的磁盘结构非常简单。
在文件中的固定位置,很可能首先,您有一个包含有关磁盘的一些信息的结构。然后是“FAT”,一个简单结构的表格,详细说明了磁盘上的文件。这基本上是一个固定大小的结构表,类似于:
struct FATEntry
{
char name[20]; /* Name of file */
uint32_t pos; /* Position of file on disk (sector, block, something else) */
uint32_t size; /* Size in bytes of file */
uint32_t mtime; /* Time of last modification */
};
在此表之后,您有一个固定大小的区域,用于磁盘上的空闲块位图。如果文件系统可以动态增长或收缩,则可能不需要位图。然后是实际的文件数据。
对于这样的系统,所有文件都必须连续布局在磁盘上。当您添加、删除和调整文件大小时,这将导致碎片化。
另一种方法是使用链表方法,例如在旧的 Amiga 文件系统上使用。使用这种方案,所有块都是简单的链表。
就像之前你需要一个实际磁盘数据的结构,可能还有一个显示空闲/分配磁盘块的位图。磁盘数据结构中唯一需要的字段是指向第一个文件的“指针”。
指针我的意思是一个整数,指出一个块在磁盘上的位置。
文件本身可以类似于上面的类 FAT 系统:
struct FileNode
{
char name[12]; /* Name of file */
uint32_t next; /* Next file, zero for last file */
uint32_t prev; /* Previous file, zero for first file */
uint32_t data; /* Link to first data block */
uint32_t mtime; /* Last modification time */
uint32_t size; /* Size in bytes of the file */
};
数据块本身就是链表:
struct DataNode
{
uint32_t next; /* Next data block for file, zero for last block */
char data[BLOCK_SIZE - 4]; /* Actual data, -4 for the block link */
};
链表文件系统的好处是它永远不会碎片化。缺点是您可能必须跳过整个磁盘来获取数据块,并且数据块不能完全使用,因为它们至少需要一个链接到下一个数据块。
第三种方式,在类 Unix 系统中很常见,是让文件数据包含一组指向数据块的链接。这样数据块就不必连续存储在磁盘上。它将包括一些与链表方法相同的缺点,因为块可以存储在整个磁盘上,并且文件的最大大小受到限制。一个优点是可以充分利用数据块。
这样的结构可能看起来像
struct FileNode
{
char name[16]; /* Name of file */
uint32_t size; /* Size in bytes of file */
uint32_t mtime; /* Last modification time of file */
uint32_t data[26]; /* Array of data-blocks */
};
上述结构将最大文件大小限制为 26 个数据块。