C:创建存档文件头

C:创建存档文件头,c,C,我正在使用C中的POSIXAPI系统调用创建一个文件归档器/提取器(如tar)。我已经完成了部分归档 我想知道是否有人可以帮助我使用一些C源代码(使用上面的代码)为C中的文件创建文件头(其中头充当索引),它描述文件属性/元数据(名称、日期时间等)。到目前为止,我所做的只是理解(不确定这是否正确)创建它需要的文件头 一个用于保存元数据的结构,需要lseek来查找文件的开头/结尾 比如: FileName=file.txt FileSize=0 FileDir=。/诸如此类 FilePerms=00

我正在使用C中的POSIXAPI系统调用创建一个文件归档器/提取器(如tar)。我已经完成了部分归档

我想知道是否有人可以帮助我使用一些C源代码(使用上面的代码)为C中的文件创建文件头(其中头充当索引),它描述文件属性/元数据(名称、日期时间等)。到目前为止,我所做的只是理解(不确定这是否正确)创建它需要的文件头 一个用于保存元数据的结构,需要lseek来查找文件的开头/结尾 比如:

FileName=file.txt FileSize=0

FileDir=。/诸如此类

FilePerms=000

\n\n

计划的归档部分有以下过程:

  • 从命令行获取所有文件的列表。(我可以做这部分)
  • 创建一个结构来保存每个文件的元数据:名称(255个字符)、大小(64位整数)、日期和时间以及权限
  • 对于每个文件,获取其统计信息
  • 将每个文件的统计信息存储在结构数组中
  • 打开档案进行写作。(我可以做这部分)
  • 编写标题结构
  • 对于每个文件,将其内容附加到存档文件(在每个文件的结尾/开头)
  • 关闭存档文件。(我可以做这部分)
  • 尽管我知道头文件需要做什么,但我在创建整个头文件时遇到了困难,正如我不能做的位上面的编号点所述(2,3,4,6,7)

    任何帮助都将不胜感激。
    谢谢。

    您可以通过stat()系统调用获取每个文件的信息

    对于标题的编写,这里有两个解决方案

    琐碎而邪恶:

    struct file_header {
    ... data you want to put in 
    } fhdr;
    
    fwrite(file, fhdr, sizeof(fhdr));
    
    这是有害的,因为结构打包因机器而异,字节顺序和基本类型(如“int”)的大小也是如此。当程序编写的文件在另一台机器上编译时,或者在某些情况下,甚至在同一台机器上使用另一个编译器时,程序可能无法读取该文件

    不平凡但安全:

    char name[xxx];
    uint32_t length; /* Fixed byte length across architectures */
    ...
    
    fwrite(file, name, sizeof(name));
    length=htonl(length); /* Or something else that converts 
                             the length to a known endianness */
    fwrite(file, &length, sizeof(length);
    
    就我个人而言,我不喜欢htonl()和朋友们,我更喜欢使用移位运算符(可以使用移位运算符编写)编写将uint32_t转换为uchar[4]的代码,因为C甚至不确定内存中整数的格式。在实践中,你会很难找到一些不存储Unt32×T的4字节8位的东西,但这是一件需要考虑的事情。 上面列出的变量可以是结构中的结构成员。在读取时反转过程留给读者作为练习。

    注意,有几种方法可以创建归档文件头。如果跨平台可移植性将成为一个问题,或者如果您需要在同一平台上切换软件的32位和64位版本,那么您需要确保在所有平台上完全理解字段的大小和布局

    每文件元数据 一种方法是使用具有已知大小和尾数类型的固定格式二进制头。这就是ijw的建议。但是,您需要处理长文件名,因此需要存储一个长度(可能是2字节无符号整数),然后使用实际路径名

    另一种方法是使用可打印字段(通常称为ASCII格式,尽管这有点用词不当),这也是目前普遍流行的技术。时间记录为从历元转换为字符串以来的十进制秒数,等等。这是现代
    ar
    档案使用的;这就是GNU
    tar
    所做的(或多或少;有一些历史上的怪癖使得这一点更加令人困惑);这就是cpio-c(这通常是现在的默认设置)所做的。字段可以用空值或空格分隔;有一种简单的方法可以检测收割台的末端;标题包含有关文件名的信息(不一定像您希望或期望的那样直接,但同样,这通常是因为格式经过多年的演变),然后是实际数据。不知何故,您知道每个字段的大小,以及标头描述的文件,以便可靠地读取数据

    效率是个骗人的把戏。与第一次磁盘访问相比,文本格式的转换非常迅速,基本上没有可测量的性能问题。而且保证的可移植性通常远远超过使用二进制数据格式带来的(微观)性能好处——当二进制数据必须在输入或输出时进行转换以使其转换为体系结构无关的格式时,情况更是如此

    中央索引与分布式索引

    另一个要考虑的问题是存档中的文件索引是集中式的(在前端还是在结尾)还是分布式的(每一个文件的元数据在文件的数据之前)。每种格式都有一些优点-通常,系统使用分布式版本,因为您可以为每个文件编写信息,而不知道总共要处理多少文件(例如,因为您递归地归档目录的内容)。在前面有一个中心索引意味着您可以列出文件而不必读取整个归档文件-分布式元数据意味着您必须读取整个文件。然而,中央索引使档案馆的建设复杂化

    请注意,即使使用分布式索引,通常也需要整个归档文件的头,以便能够检测到文件的格式是否符合预期。通常,对于
    ar
    归档文件,通常在PDF文件的开头有某种标记信息(
    !\n
    %PDF-1.2\n
    等),以确保该文件包含您期望的内容。可能存在一些总体(归档级别)元数据。然后,您将获得第一个文件元数据,后面是文件数据,重复
    "%20" PRIu64 " %06o %-.32s %-.32s %26" PRIu64 " %-4d %s\n"
    
    "%" SCNu64 " %o %.32s %.32s %" SCNu64 "%d"