【问题标题】:C binary file versus text file efficiencyC 二进制文件与文本文件的效率
【发布时间】:2015-04-02 11:58:45
【问题描述】:

我是 C 的新手,我需要一些帮助。 假设我只需要在文件中存储 6 位数字。 (让我们假设 int 的大小等于 4) 使用文本文件或二进制文件会更有效(就内存而言)?我不确定如何面对这个问题,欢迎任何帮助

【问题讨论】:

  • 由于数据在磁盘上,内存与此无关。将其从磁盘中取出 是另一回事。正如您所写的那样,您的问题没有说明用例,因此除了纯粹的猜测之外,您的问题似乎无法确定。我明白为什么面对这个“问题”会很困难,因为实际上没有一个人被泄露。在这两种情况下,存储形式的选择各有利弊。其中任何一项是否适用于您都需要更多信息。
  • 磁盘比内存慢几百万倍......
  • 如果您的意思是“就文件大小而言”,那么当然 4 小于 6,因此如果您使用二进制而不是文本,文件将小 33%。实际上更多,因为您需要将数字之间的分隔符作为文本,而不是二进制数之间。
  • @unwind 我认为他的意思是int 的大小是 4 个字节。所以无论是二进制还是文本,一个 6 位数字仍然是 4 个字节。
  • @RedSerpent 是的,这就是我的阅读方式,但当然,像“123456”这样的六位数字如果存储为文本,则不会是 4 个字节。我现在很困惑。

标签: c file text binary


【解决方案1】:

二进制文件基本上是任何不是“面向行”的文件。除了实际书写的字符和换行符之外还有其他符号的任何文件。

通常当您以文本模式编写文件时,任何新行 \n 都会被转换为回车 + 换行符 \r\n

相对于文本文件使用二进制文件无法实现任何内存效率,文件存储在磁盘上而不是内存中。这完全取决于您要对文件执行什么操作以及您希望如何格式化它。

由于您使用的是纯整数(无论 int 大小是多少),因此使用文本或二进制文件会对性能产生相同的影响(这意味着您选择使用哪种类型不会有任何区别) .

如果您以后想在文本编辑器中修改或读取文件,最好使用文本模式写入文件。

【讨论】:

    【解决方案2】:

    大多数人将文件分为两类:二进制文件和 ASCII(文本)文件。你实际上已经与两者一起工作了。您编写的任何程序(C/C++/Perl/HTML)几乎肯定是一个 ASCII 文件。

    ASCII 文件定义为由 ASCII 字符组成的文件。它通常是通过使用诸如 emacs、pico、vi、记事本等文本编辑器创建的。有更高级的编辑器用于编写代码,但它们可能并不总是将其保存为 ASCII。 ASCII 是国际标准。

    计算机科学就是创造良好的抽象。有时它会成功,有时它不会。好的抽象都是关于呈现用户可以使用的世界视图。最成功的抽象之一是文本编辑器。

    当您编写程序并输入 cmets 时,很难想象这些信息没有以字符形式存储。 ASCII/文本文件实际上存储为 0 和 1。

    文件存储在磁盘上,磁盘有某种方式来表示 1 和 0。我们只称它们为 1 和 0,因为这也是一种抽象。无论使用哪种方式将 0 和 1 存储在磁盘上,我们都不在乎,只要我们能以这种方式考虑它们。

    实际上,ASCII 文件基本上是二进制文件,因为它们存储二进制数。也就是说,ASCII 文件存储 0 和 1。

    ASCII 文件和二进制文件的区别?

    ASCII 文件是存储 ASCII 代码的二进制文件。回想一下,ASCII 代码是存储在一个字节中的 7 位代码。更具体地说,有 128 种不同的 ASCII 码,这意味着只需要 7 位来表示一个 ASCII 字符。

    但是,由于最小的可用大小是 1 字节,所以这 7 位是任何字节的低 7 位。最高有效位是 0。这意味着,在任何 ASCII 文件中,您都在浪费 1/8 位。特别是,每个字节的最高有效位都没有被使用。

    虽然 ASCII 文件是二进制文件,但有些人将它们视为不同类型的文件。我喜欢将 ASCII 文件视为特殊类型的二进制文件。它们是二进制文件,其中每个字节都用 ASCII 码编写。

    完整的通用二进制文件没有这样的限制。任何 256 位模式都可以在二进制文件的任何字节中使用。

    我们一直在处理二进制文件。可执行文件、目标文件、图像文件、声音文件和许多文件格式都是二进制文件。使它们成为二进制的原因仅仅是二进制文件的每个字节都可以是 256 位模式之一。它们不限于 ASCII 码。 ASCII 文件示例

    假设您正在使用文本编辑器编辑文本文件。因为您使用的是文本编辑器,所以您几乎是在编辑 ASCII 文件。在这个全新的文件中,您输入“cat”。也就是说,字母“c”,然后是“a”,然后是“t”。然后,保存文件并退出。

    会发生什么?暂时,我们不会担心打开文件、修改文件和关闭文件意味着什么的机制。相反,我们关心的是 ASCII 编码。

    如果您查找 ASCII 表,您会发现 0x63、0x61、0x74 的 ASCII 代码(0x 仅表示值是十六进制,而不是十进制/基数 10)。

    Here's how it looks:
    ASCII   'c'        'a'          't'
    Hex     63          61          74
    Binary  0110 0011   0110 0001   0111 1000
    

    每次输入 ASCII 字符并保存时,都会写入与该字符对应的整个字节。这包括标点符号、空格等。

    因此,当您键入“c”时,它会以 0110 0011 的形式保存到文件中。

    现在,有时文本编辑器会输入您可能意想不到的字符。例如,一些编辑“坚持”每行以换行符结束。

    文件唯一可以在行尾缺少换行符的地方是最后一行。一些编辑器允许最后一行以换行符以外的内容结尾。一些编辑器在每个文件的末尾添加一个换行符。

    不幸的是,即使换行符也不是通用的标准。在 UNIX 文件中使用换行符很常见,但在 Windows 中,通常使用两个字符来结束每一行(回车符,换行符,我相信是 \r 和 \n)。只需要一个字符时为什么要两个字符?

    这可以追溯到打印机。在过去,打印机返回到行首的时间等于输入两个字符的时间。因此,在文件中放置了两个字符,让打印机有时间将打印球移回行首。

    这个事实并不是那么重要。这主要是琐事。我提出它的原因是为了以防您想知道为什么从 Windows 向 UNIX 传输文件有时会产生有趣的字符。 编辑二进制文件 既然您知道在 ASCII 文件中键入的每个字符都对应于文件中的一个字节,那么您可能会理解为什么很难编辑二进制文件。

    如果你想编辑一个二进制文件,你真的很想编辑单个位。例如,假设你想写二进制模式 1100 0011。你会怎么做?

    你可能太天真了,在文件中输入以下内容:

    11000011
    

    但是您现在应该知道,这并不是在编辑文件的单个位。如果您输入“1”和“0”,您实际上输入的是 0x49 和 0x48。也就是说,您要在文件中输入 0100 1001 和 0100 1000。您实际上是(间接)一次输入 8 位。

    有些程序允许您输入 49,它会将其转换为单个字节 0100 1001,而不是 '4' 和 '9' 的 ASCII 码。您可以将这些程序称为十六进制编辑器。不幸的是,这些可能并不那么容易获得。编写一个程序,读取一个看起来像十六进制对的 ASCII 文件,然后将其转换为具有相应位模式的真正二进制文件,这并不难。

    也就是说,它需要一个看起来像这样的文件:

    63 a0 de
    

    并将此 ASCII 文件转换为以 0110 0011 开头的二进制文件(二进制为 63)。请注意,此文件是 ASCII,这意味着真正存储的是 '6'、'3'、''(空格)、'a'、'0' 等的 ASCII 代码。程序可以读取此 ASCII 文件,然后生成适当的二进制代码并将其写入文件。

    因此,ASCII 文件可能包含 8 个字节(6 个用于字符,2 个用于空格),输出二进制文件将包含 3 个字节,每个十六进制对一个字节。

    编写二进制文件

    为什么人们仍然使用二进制文件?一个原因是紧凑性。例如,假设您要写入数字 100000。如果您以 ASCII 形式输入,则需要 6 个字符(即 6 个字节)。但是,如果将其表示为无符号二进制,则可以使用 4 个字节将其写出。

    ASCII 很方便,因为它往往是人类可读的,但它会占用大量空间。您可以使用二进制文件更紧凑地表示信息。

    例如,您可以做的一件事是将对象保存到文件中。这是一种序列化。要将其转储到文件中,请使用 write() 方法。通常,您将指向对象的指针和用于表示对象的字节数(使用 sizeof 运算符确定)传递给 write() 方法。然后,该方法将内存中出现的字节转储到文件中。

    然后,您可以使用相应的 read() 方法从文件中恢复信息并将其放入对象中,该方法通常采用指向对象的指针(并且它应该指向已分配内存的对象,无论它是静态或动态分配)和对象的字节数,并将字节从文件复制到对象中。

    当然,你必须小心。如果您使用两种不同的编译器,或者将文件从一种机器传输到另一种机器,则此过程可能不起作用。特别地,对象可以以不同方式布置。这可以像字节顺序一样简单,或者可能存在填充问题。

    这种将对象保存到文件的方式既好又简单,但它可能不是那么便携。此外,它相当于浅拷贝。如果您的对象包含指针,它将写出文件的地址。这些地址可能完全没有意义。地址在程序运行时可能有意义,但如果您退出并重新启动,这些地址可能会改变。

    这就是为什么有些人发明了自己的对象存储格式:以提高可移植性。

    但是,如果您知道您没有存储包含指针的对象,并且您是在您编写文件的同一类型的计算机系统上读取文件,并且您使用的是相同的编译器,那么它应该可以工作。

    这是人们有时更喜欢写出整数、字符等而不是整个对象的原因之一。它们往往更便携。

    ASCII 文件是由 ASCII 字符组成的二进制文件。 ASCII 字符是存储在一个字节中的 7 位编码。因此,ASCII 文件的每个字节都将其最高有效位设置为 0。将 ASCII 文件视为一种特殊的二进制文件。

    通用二进制文件使用所有 8 位。二进制文件的每个字节都可以有完整的 256 个位串模式(而 ASCII 文件只有 128 个位串模式)。

    可能有一段时间,Unicode 文本文件变得更加普遍。但目前,ASCII 文件是文本文件的标准格式。

    【讨论】:

    • 很多话。有些很有见地。谢谢。
    猜你喜欢
    • 1970-01-01
    • 2015-04-08
    • 1970-01-01
    • 1970-01-01
    • 2018-10-04
    • 1970-01-01
    • 1970-01-01
    • 2013-04-19
    • 2014-01-18
    相关资源
    最近更新 更多