fread 和 fwrite 如何区分 C 中的不同数据(类型)?

用户12055579

我正在使用程序和 C(使用 Ubuntu 及其 bash)并使用它来操作二进制数据文件。首先,当我使用fopen(filename, 'w')它时会创建一个文件,但没有任何扩展名。但是,当我使用vim filename时,它会以某种二进制形式打开它。

对于这个问题,当我使用fwrite(array, sizeof(some struct), # of structs, filePointer)它时(我不确定如何以二进制方式写入)到文件中。当我fread(anotherArray, sizeof(same struct), same # of structs, anotherFilePointer)以某种方式使用时,我神奇地知道如何以二进制形式读取每个结构,并通过知道它的大小和读取量将其放入数组中。如果我输入的十进制值小于# of structs参数中的结构数,会发生什么如何fread知道正确阅读什么?仅通过查看大小而不知道它是什么类型的数据,它是如何读取数据的?

知乎

fwrite将存储对象的内存字节写入输出流,fread并将字节从输入流读取到其地址作为参数的内存中。没有对存储在该内存中的 C 对象的类型和表示做任何假设。

因此,可能会出现许多问题:

  • 基本类型的表示可以从一个编译器到另一个编译器、一个机器到另一个机器、一个操作系统到另一个,甚至可能取决于编译器开关。仅当您知道将文件读回字节兼容结构时,写入基本类型的内存表示的字节才有意义。
  • 访问输入和输出文件的模式很重要:正如您提到的,文件必须以二进制模式打开,以避免内存表示和文件内容之间的任何转换,例如遗留系统上的文本文件会发生什么。例如,MS-Windows 上的文本模式会导致0A字节0D 0A在输出时转换为序列,而0D在输入时字节将被剥离,从而导致0D初始内容中孤立字节的内容不同。
  • 如果 C 结构包含指针,则写入输出的字节表示这些指针,而不是它们指向的值。将这些值读回内存很可能会创建无效的指针,并且不太可能有任何意义。
  • 如果 C 结构体末尾有一个灵活的数组,则其内容不包含在由sizeof(T)写入fwrite或读取字节中fread
  • C 结构可能包含成员之间的填充,导致输出文件包含非确定性字节,这在某些情况下可能是一个问题。
  • 如果 C 结构具有仅包含部分有意义内容的char数组,例如包含 C 字符串的数组,请注意fwrite将写入超出空终止符的字节,这些字节应该没有意义,但可能是敏感信息,例如密码片段或其他有意义的数据。仔细擦除这样的数组可以避免这个问题,但是填充字节不能被可靠地擦除,所以这个方案并不完美。

由于上述所有原因和其他原因,读取/写入二进制数据将保留给程序员确切知道发生了什么的非常特定的情况。出于其他目的,最好以人类可读的形式保存为文本文件。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章