二进制文本模式文本操作 - 文本模式 - 性能问题

Alc*_*ott 9 c c++ file-io

在许多项目中,我看到数据对象/结构以二进制模式写入文件,然后再次以二进制模式从文件中检索它们.

我想知道为什么他们在二进制模式下这样做?文本和二进制模式之间的任何性能差异?如果没有,那么何时使用二进制模式或文本模式?

小智 16

二进制更快.考虑一个存储在32位(4字节)中的整数,例如123456.如果你把它写成二进制(这是它在计算机中的表示方式),则需要4个字节(忽略项之间的填充以便在结构中对齐) ).

要将数字写为文本,必须将其转换为字符串(转换的一些开销和存储的内存),然后将其写出来,至少需要6个字节,因为有6个字符来重新显示数字.这不包括任何额外的填充,例如用于对齐的空间或用于读取/分离数据的分隔符.

现在,如果你考虑它你有几千个项目,额外的时间可以累加,需要更多的空间,这需要更长的时间来读入,然后有额外的时间转换回二进制存储后,你已经读取了值进入记忆.

文本的优点是,它更容易为人们阅读,而不是尝试读取数据的二进制数据或十六进制转储.

  • 我发现你的答案更容易理解.:-) (2认同)

Som*_*ude 6

如果您的程序是唯一要使用该文件的程序,则可以使用二进制文件"按原样"保存内部结构.

但是,如果您想与其他程序或通过Internet交换文件,那么二进制格式就不那么好了.想想关于big-endian与little-endian机器的问题的例子.此外,文件或数据的接收者很可能无法访问您的代码和结构,因此基于文本的格式可能更容易解析并实现到自己的结构中.

关于性能,直接读取和编写内部结构确实会更快,因为您不必将它们(也称为编组)转换为另一种格式.


Jam*_*nze 5

从历史上看,二进制模式是提供对底层流的或多或少的透明访问; 文本模式"标准化"为标准文本表示,其中行由单个'\n' 字符终止.另外,系统可以对二进制文件的大小施加限制,例如通过要求它是128或512字节的倍数.(第一个是CP/M的情况,是DEC OS中的第二个.)文本文件没有这个限制,并且在操作系统强加它的情况下,库通常会引入一个额外的文件结束字符用于文本文件.(即使在今天,大多数Windows库在文本模式下读取时都会识别旧的CP/M文件结尾0x1A.)由于这些考虑,文本模式仅在一组有限的二进制值上定义.(但是如果你把200个字节写入二进制文件,当你重新读取它时可能会得到256或512.从历史上看,二进制文件只能用于其他结构化的文本,这样你就可以识别出逻辑结束了,忽略这些额外的字节.)

此外,您可以在以二进制模式打开的文件中任意搜索; 你只能在文本模式中寻找开头或者你以前记忆的位置.(这是因为行结束映射意味着文件中的位置与文本流中的位置之间没有简单的关系.)

请注意,这与输出是否格式化是正交的:如果使用<<(并使用输入>>)输出,则无论文件的打开模式如何,都会格式化IO.格式化始终是文本; iostream旨在操纵文本流,并且仅对非文本输入和输出提供有限支持.

今天,情况有所改变:在许多情况下,我们希望我们编写的内容可以从其他机器读取,这假设一种定义良好的格式,这可能不是本机使用的格式.(因此,例如,互联网期望两个字节序列0x0D,0x0A作为行结束,这与Unix和许多其他操作系统内部使用的不同.)如果可移植性是一个问题,通常定义一种格式,写它是显式的,并使用二进制模式来确保你所写的内容正是所写的; 类似地,在输入时,您使用二进制格式,并手动处理约定.但是,如果您只是写入未共享的本地磁盘,则文本模式可以正常工作.

同样,这两个都适用于文本.如果你想要二进制格式,你必须使用二进制模式,但这远远不够.您必须自己实现所有格式化的IO.在这种情况下,我通常不使用std::istreamstd::ostream(其抽象是文本),而是定义我自己的流类型,派生自std::ios_base (用于错误处理约定)和使用std::streambuf(用于物理IO).

最后,不要忽视所有 IO都以某种方式格式化的事实.只是将一块内存写入文件意味着该格式是当前实现发生的任何内容(通常是未记录的,这意味着您将来可能无法读取它).如果您所做的只是溢出到磁盘,并且您唯一一次读取它是使用相同的程序,使用相同的编译器编译同一版本,使用相同的编译器选项,那么您可以只转储内存,提供有问题的内存只是POD,并且不包含指针.否则,您必须定义(并记录)您使用的格式并实现它.在这种情况下,我建议使用现有的格式,如XDR,而不是发明自己的格式:编写"使用XDR格式"作为文档更容易,而不是描述所有不同的实际位和字节布局类型.


Sin*_*all 3

如果你以文本模式读/写文件,那么你就是在操作文本。它可能是编码错误和操作系统特定格式更改的问题,尽管有时它可能工作得很好。但在二进制模式下,您将不会满足这些限制。此外,文本模式可能会用\n字符做一些有趣的事情,例如将它们替换为\n\r

例如,Fopen参考文献指出:

对于文本文件,根据应用程序运行的环境,输入/输出操作中可能会发生一些特殊字符转换,以使其适应系统特定的文本文件格式。在许多环境中,例如大多数基于 UNIX 的系统,以文本文件或二进制文件打开文件没有什么区别;两者的处理方式完全相同,但建议区分以实现更好的可移植性。