基本上我需要实现一个程序来充当用户空间文件系统,该系统实现非常简单的操作,例如查看磁盘上的内容,将文件复制到本机文件系统或从本机文件系统复制到我的文件系统(包含在一个名为“disk01”的文件,并从我的文件系统中删除文件。
我基本上正在寻找一个跳板或一些提示我可以从哪里开始,因为我不确定如何创建我自己的“磁盘”并将其他文件放入其中,这是一项家庭作业。
只是一个寻找方向的C ++学生。
修改
我知道这个概念已经在几个不同的地方用作“VFS”或虚拟文件系统,有点像zip文件(你只能通过一个可以处理zip文件的程序查看内容)。我基本上是在尝试编写类似于zip或winrar等的自己的程序,但不是那么复杂且功能丰富。
感谢您的建议到目前为止!你们都是一个巨大的帮助!
答案 0 :(得分:6)
创建类似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个数据块。
答案 1 :(得分:1)
打开文件以进行非破坏性读/写。使用fstream,这可能是fstream stream(filename)
。
然后使用搜索功能移动它。如果您使用的是C ++ fstream,则为stream.seekg(position)
。
然后你需要二进制读写功能,这样你就可以使用stream.read(buffer, len)
和stream.write(buffer, len)
。
启动文件系统的简单方法是确定块大小。过去大多数人使用512字节。您可以这样做或使用4K或使其完全可调。然后你在开头附近留出一个自由空间地图块。这可能是每个块一点,或者如果你是每个块一个字节是懒惰的。然后,你有一个根目录。 FAT这样做很简单:它只是一个名称列表,一些元数据,如时间戳,文件大小和块偏移。我认为FAT块有一个指向文件中下一个块的指针,这样它就可以分割文件而不需要在写入时运行碎片整理。
然后你搜索目录,找到文件,转到偏移量并读取块。
真正的文件系统变得复杂的是硬件任务,比如为文件分配块,这样他们就有空间在末端成长而不浪费空间。处理碎片。在多个线程或程序同时写入时具有良好性能。面对意外的磁盘错误或断电,可以实现强大的恢复。