c - 从C中的字符数组中提取一组变量[linux]

标签 c linux string file

我有一个程序,简而言之,它需要一个文件目录,将每个文件的元数据和内容写入一个文件。第二步是从文件中恢复目录。
我想不出一种方法来分离文件中的元数据,以便在任何情况下都可以轻松提取。这主要是因为Linux允许使用几乎所有字符来命名目录或文件(除了/\0)。因此,任何其他字符都可以只是文件名的一部分或其内容的一部分。
缩短的文件条目示例:
目录名/子目录/文件名[分隔符]9999[分隔符]1234[分隔符]内容
任何想法都将不胜感激。

最佳答案

至少有四种基本方法:
对文件名进行编码
您可以使用各种编码对文件名进行编码,以便编码的版本仅包含可移植的可接受字符。
Linux中的目录项基本上只是8位字节的非空序列,以零(\0)结尾,可能不包含正斜杠(/)。序列.保留给当前目录,而..保留给父目录。
您可以使用各种可能的编码。WikipediaBinary-to-text categoryBinary-to-text encoding page包含一些您可能希望查看的更常见示例。
逃逸
与C对控制字符使用反斜杠转义的方式类似(例如,在Unix/Linux环境中引用ASCII LF或newline的\n),可以使用特殊字符转义用作分隔符或以其他方式特殊处理的字符。(注意,为了便于移植,您应该将这些文件视为二进制文件,而不是UTF-8编码的文件,除非特定字节具有特定的含义。)
尽管基本上不限制转义的方式,但最容易实现的方法之一是使用一个转义字符(比如%)和两个十六进制字符来指定转义字符。
结构化文本
您可以使用最小的标记语言,甚至像XML这样的语言来描述每个目录条目。
虽然标记会增加每个目录项的长度,但是扩展起来很简单。例如,您可能希望在某个时候添加对扩展属性的支持;以向后兼容的方式添加这些属性是很简单的。
当然,与完整的标记语言不同,您可以只在逻辑上为每个目录条目使用associative array,并让您的文件成为这些关联数组的数组。其中一个关联数组键将指定目录项名称,一个将指定数据部分,依此类推。
关联数组的逻辑数组的最小实现是在每个字段的开头使用固定宽度的键。实际上,这是非常常见的:文件格式,如JFIF(最常见的JPEG文件格式)、TIFFPNG。事实上,添加到JPEG图像的EXIF数据相机使用了这种精确的扩展性。
二进制数据结构
您可以使用二进制数据结构,而不是将特定字节作为分隔符。类似于上述JFIF等。文件格式,存档文件由一个或多个段组成。每个段都包含一个长度(以字节为单位指定段的长度)和一个类型标识符。段的内容根据类型进一步结构化。
文件名也可以用段(在“文件段”内)来描述。因此,文件名可以由任何字节值组成,包括\0/,尽管您的应用程序当然应该验证文件名对于当前操作系统是可接受的,并且可能在必要时应用适当的转换。(类似的工具如tardo。)
你应该注意另外两个皱纹。一种是字节顺序;不能只说四个字节对一个单词进行编码,还必须说明哪个字节的顺序最重要/最不重要。另一个是文件长度。许多旧实用程序假定文件长度永远不会超过232字节,因此所有长度都可以用4字节编码。这不再是事实。幸运的是,您可以假设在可预见的将来,文件长度不会超过264字节;也就是说,使用8字节编码长度就足够了。(不,因为这是不可思议的——不是——,但仅仅是因为其他人也一样。)
根据你使用的方法有实际效果。一般认为,二进制数据结构对数据损坏的鲁棒性较差,但它们确实允许更快的扫描(因为可以跳过文件数据段之类的内容,而不必从存储中检索)。此外,人类可以解析转义和结构化文本,但很少(完全)编码或二进制数据;编码和二进制数据通常需要特殊工具。
就我个人而言,我确实更喜欢二进制方法,但我使用了结构化文本,特别是在人工检查存储数据非常有用的情况下。
问题?

关于c - 从C中的字符数组中提取一组变量[linux],我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21403048/

相关文章:

java - 如何正确为带有转义字符的 String.matches() 创建正则表达式?

java - 使用 for 循环转换输入

头文件位于其他目录中的 C Makefile

c - 多线程和strtok

c - else if 语句错误,我如何转到嵌套 for 循环中的下一个语句

c++ - 如何让我的用户级应用程序通过管道与根级应用程序通信?

linux - ELF NT_FILE 注释的含义

c - PortAudio 回调,并在别处更改变量

c - mmap、msync 和 linux 进程终止

java - 如何在java中处理字符串编码?