【问题标题】:File Binary vs Text文件二进制与文本
【发布时间】:2013-05-21 12:56:05
【问题描述】:

在某些情况下我必须更喜欢二进制文件而不是文本文件吗?我使用 C++ 作为编程语言?

例如,如果我必须存储一些大文本文件,是使用文本文件还是二进制文件更好?

编辑

目前该文件不需要人类可读。是否有一些性能差异、安全差异等?

编辑

抱歉省略了其他要求(感谢 Carey Gregory)

  • 要保存的记录是ascii编码的
  • 文件必须加密(AES)
  • 机器可以随时关机。所以我必须尽量避免错误。
  • 我想知道如果文件在程序之外发生变化,我想我会使用文件的 sha1 摘要。

【问题讨论】:

  • 您为什么不简化问题,直接告诉我们您的要求是什么?
  • 如果您的数据是 ASCII 文本,那么您为什么要将其存储为其他内容?除非您有压缩或加密等要求,否则没有理由更改数据的编码,并且有很多很好的理由不这样做。
  • 另一个要求是加密 (AES)
  • 哇,省略了一个相当重要的要求。

标签: c++ file


【解决方案1】:

作为一般规则,定义文本格式并使用它。很多 更容易开发和调试,而且更容易看到是什么 如果它不起作用就会出错。

如果您发现文件变得太大,或者需要 很多时间通过电线传输,考虑压缩它们。 压缩的文本文件通常比您可以使用的要小 二进制。或者考虑一种不那么冗长的文本格式;这是可能的 可靠地传输数据的文本表示 比 XML 使用的字符少很多。

最后,如果您最终不得不使用二进制文件,请尝试选择 现有格式(例如 Google 的协议块),或基于您的 现有格式的格式。请记住:

  • 二进制比文本多很多,因为你实际上 必须再次编写所有 << 运算符,包括那些 在标准库中。

  • 二进制文件很多更难调试,因为你不能 轻松查看您实际做了什么。

关于您上次的编辑:

  • 加密后,结果将是二进制的。你可以 使用二进制的文本表示(base64 或类似的), 但结果不会比二进制文件更具可读性,所以 这不值得费心。如果您正在加密, 在写入磁盘之前,您会自动丢失所有 文字的优点。

  • 关于关机的问题意味着你不能使用 直接ofstream。您必须使用 完整事务完整性的必要选项(O_SYNC as Unix 下open 的标志)。您必须将每条记录写为 向系统发出单个 write 请求。

  • 有一个校验和总是一个好主意,以防万一。如果 如果您担心安全性,SHA1 是一个不错的选择。但保持 请记住,如果有人可以访问该文件,并且想要 故意改变它,他们可以重新计算 SHA1 和 也插入新值。

【讨论】:

  • 感谢您的建议。我会尝试应用它。非常感谢
  • 对于校验和...文件是加密的(带有摘要)所以我想我不必担心恶意更改。
  • 为了舒适的编辑; XML 到二进制和/或反之亦然。这将加快调试过程。尽管如此,二进制文件格式似乎并不是一个节省时间的解决方案。
【解决方案2】:

所有文件都是二进制的;其中的数据是某些信息的二进制表示。如果您必须存储大量文本,则文件将包含该文本的二进制表示。 “二进制文件”和“文本文件”之间的区别在于创建后者涉及在保存数据之前将数据转换为文本形式。这通常是为了让人类可以阅读。

在存储供计算机使用的数据时,通常会区分二进制和文本。通常,此数据不会是文本 - 它可能是数字配置值列表,例如:1, 2, 3。

如果您以文本格式存储此文件,您的文件可能包含人类可读的数字列表,如果您在记事本中打开文件,您可能会看到每行一个数字。但是你在这里实际保存的不是二进制值1, 2, 3 - 你保存的是一个字符串"1\n2\n3\n"。请注意,此字符串长度为 6 个字符,二进制值(假设为 ASCI)实际上是 49, 10, 50, 10, 51, 10!

如果相同的数据以二进制格式存储,您会将数字存储在最小的有用空间中,并将文件作为单个字节写入,这些字节通常只能由创建它们的代码读取。在记事本中打开此文件可能会显示垃圾字符,因为数据作为文本没有意义。在这种情况下,您将保存一个包含实际值 { 1, 2, 3 } 的字节数组 - 甚至是嵌入三个值的单个字节。这可能比人类可读的等价物要小得多。

【讨论】:

  • 按照他的说法,反正他所有的数据都是文本,所以二进制格式可能会稍微大一些(因为它需要说明后面是文本)。另一方面,他提到了加密:加密后,他只得到一个原始字节流,任何将其转换为文本的尝试都会增加大小,并且不会使其更具可读性。
  • 是的,在人们回答后,加密是一个相当大的要求:-) 我将把我的答案留在这里以供参考,但很明显,实际问题是一个公平的方式最初发布。
  • 重新加密,肯定会改变二进制和文本的平衡。
【解决方案3】:

二进制文件像所有其他文件一样存储一系列字节。您可以存储数字值,例如每 4 个字节的整数、每单字节的字符,甚至是序列化的类对象以及您想要的任何内容。

当您知道如何读取二进制文件(即您知道其中存储了什么)时,您可以从中提取所有信息。但是,文本文件使用 UTF8、ANSI 等文本编码,它们旨在对要由文本编辑器处理的文本字符进行编码。

【讨论】:

    【解决方案4】:

    二进制文件仅供机器解释,而文本文件,人类也可以打开和解释其内容。

    所以这取决于您是否希望您的文件可供人类阅读。

    【讨论】:

      【解决方案5】:

      这取决于很多因素。我现在能想到两个:

      • 您是否要求文件可供人类阅读?

      • 压缩是一个因素吗?一个 10 位数字至少需要 10 个字节作为文本,但可能只需要四到两个二进制。

      【讨论】:

      • 对于第二个 pont,一位数字将占用 2 个字节作为文本(因为它可能需要分隔符),但可能很容易占用 4 个二进制。
      • @JamesKanze 不要挑剔,但您假设的是一个单字节字符集,它不适用于地球上一半以上的人口。使用 Unicode,存储单个数字加分隔符至少需要 4 个字节,最多需要 8 个字节。
      • @CareyGregory 所有常用数字和大多数常用分隔符在 UTF-8 中都是一个字节。而且你不会写其他任何东西。
      • @JamesKanze 假设他确实不需要支持 CJK 语言,但如果他这样做了,他将需要 UTF-16。
      • @CareyGregory 为什么他需要 UTF-16?除非您确定该文件将仅在写入文件的机器上本地使用,否则您永远不会希望实际读取和写入 UTF-16 到文件。用于数据传输的通用约定(今天——仍然有很多遗留代码使用 ISO 8859 或 JIS)是 UTF-8,并且 UTF-8 已经过精心设计,因此 ASCII 中的所有字符都是单字节的相同的编码。
      【解决方案6】:

      存储在文本文件中的所有数据都是人类可读的图形字符。每行数据都以换行符结束。 在二进制文件的情况下 - 数据以与存储在内存中相同的格式存储。没有行或换行符。有一个文件结束标记。

      此外,二进制文件显示出更高的内存效率,因为它们以 0 和 1 的形式存储。

      【讨论】:

        【解决方案7】:

        所有数据都是二进制的。你总是需要一台机器来为你解释它。即使数据像协议缓冲区、Avro、Thrift 等一样被压缩,它也是二进制的,如果它是未压缩的,它仍然是二进制的。如果您想通过记事本读取协议缓冲区,则有两个步骤。解压,阅读。如果是文本,则不需要此解压缩步骤。加密的情况也是如此。先不加密,再读取。人类无法阅读二进制文件(正如一些评论者所提到的)。我们仍然需要记事本来解释和显示二进制文件(所谓的文本)。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2015-04-02
          • 2023-04-11
          • 2015-04-08
          • 2016-02-28
          • 2013-04-19
          • 2014-01-18
          • 1970-01-01
          • 2021-12-28
          相关资源
          最近更新 更多