在C中创建文件头(文件的元数据)

Nim*_*it 4 c file-io file

文件头包含有关文件的所有数据-元数据。我想创建一个包含元数据的空白文件,然后将其他文件内容添加到该空白文件中,并且需要更改(修改)元数据。C中是否有用于创建文件头的库?如何在C中读写文件头?

metadata =
{
file_name;
file_size;
file_type;
file_name_size;
total_files;
}
Run Code Online (Sandbox Code Playgroud)

Jon*_*ler 5

可能有许多种库可以处理特定的文件格式,例如上的变体tar,但没有一种适合您的特定标头格式。

首先,您需要确定元数据的大小是固定的还是可变的。

如果它是固定大小,则在开始时跳过那么多字节,写入文件的其余部分,然后倒回并填充元数据相对容易。如果一开始只知道可变大小的部分,则可以用相同的方式来处理它-编写第一个版本,完成后返回并编写最终版本。

如果您直到最后都不知道可变材料的大小,那么您会有些困难。您可能最终会用文件的大部分内容写一个临时文件,然后在知道所有可变大小的元数据后,将元数据标头写入新的(最终)文件,然后在临时文件之后复制该临时文件。元数据。

请注意,应在磁盘上的数据中将文件名的大小(长度)放在实际文件名之前。然后,您可以读取名称的大小,并分配正确的空间并读取正确数量的数据。在文件名本身后面放置文件名的长度确实并没有太大帮助。

您还需要考虑标题是二进制数据还是文本。文件名部分将是文本,但数字可以是2字节或4字节的二进制值,或者是ASCII(纯文本)可变长度的等价物。通常,调试文本表示形式更容易,但是如果您确实使用文本,则更有可能需要可变长度的数据。但是,您也可以始终使用固定大小的空白填充。相对于二进制,文本的另一个优势是文本可以在各种计算机体系结构之间移植,而二进制则带来了大端与小端机器的问题,依此类推。

您还应该考虑使用“幻数”来识别文件中包含正确种类的数据。“数字”可能是ASCII字符串,例如!<arch>\n某些ar标头版本中使用的ASCII字符串。或%PDF-1.3\n用于PDF文件的开头。话虽这么说tar,但在前几个字节中却没有一个神奇的数字,这在很大程度上是可以避免的,但是如今这是不寻常的设计。该file程序对魔术数字了解很多。有时会在文件中找到其数据-例如/usr/share/fileMac OS X 下的文件。


你能举例说明一下吗?

我处理的一种文件格式是用32位(带符号)数字标识的消息,消息的长度可变,因此偏移量也可变。该文件以平台无关的二进制格式编写。这些数字以高位开头,MSB在前。消息号当前限制在±99,999范围内(因此整个系统中的消息量不足200,000条)。

文件头包含:

  • 2字节(无符号)幻数
  • 文件中包含的消息数的2字节(无符号)计数,N

它后跟N个条目,每个条目描述一条消息:

  • 4字节(带符号)消息号
  • 2字节(无符号)消息长度
  • 消息开头的4字节(无符号)偏移量

N个条目按消息号的排序顺序,但是不要求消息号是连续的。缺失的数字简直就是缺失。

在N个条目之后,紧随其后的是实际的消息文本,每个消息文本均包含相应条目所标识的适当数量的字节以及ASCII NUL '\0'字节。

生成文件时,每条消息的文本都按照处理的顺序写到中间文件中,并在文件中记录消息的偏移量。消息是按顺序读取还是写入都无所谓。重要的是,从标头末尾开始的偏移量记录在标头记录中。读完所有消息后,可以按数字顺序对文件条目的内存副本进行排序,然后可以写入最终文件。首先是魔术数和消息数;然后是N条描述消息的条目;然后是从中间文件复制的消息文本。

读取消息号M很简单。您对N个条目进行了二进制搜索,找到了M的条目。如果不存在,那就对了-这是一个错误。如果存在,您将知道在文件中的位置以及文件的长度。

数据是固定的但二进制格式的事实并没有使事情复杂化。您在big-endian和little-endian机器上使用相同的功能将数字读取为原始格式。从理论上讲,您可以针对大端机器进行优化,但前提是该机器不会因数据对齐不足而出现问题。更容易忘记优化是可能的,并且只是在各处使用相同的代码。


如果将上述格式转换为文本格式,则可能为魔术数字保留了8个字节(例如)(该数字很可能是7个字母的字符串后跟换行符),并且为数字保留了6个字节消息(5位数字加换行符)。每个消息条目可以为消息编号保留6个字节(编号为±99,999),再加上一个空格,再为其保留4个字节的长度(最大8KiB),再加上一个空格,再加上一个8字节的偏移量(7位数字)加上换行符)。

MAGICNO
12345
-99999 8000 0000000
-90210   38 0008000
...
Run Code Online (Sandbox Code Playgroud)

同样,文本文件具有可读性的优点是,您可以轻松查看文件并查看数据的含义。

您可以在这个主题上有无穷的变化。