我在C中很新,我想要一些帮助。 假设我需要在文件中存储仅6位数字。 (假设int的大小等于4) 使用文本文件或二进制文件会更有效(在内存方面)?我不确定如何面对这个问题,欢迎任何帮助
答案 0 :(得分:7)
大多数人将文件分为两类:二进制文件和ASCII(文本)文件。你实际上和两者都合作过。您编写的任何程序(C / C ++ / Perl / HTML)几乎肯定都是ASCII文件。
ASCII文件定义为由ASCII字符组成的文件。它通常是使用文本编辑器创建的,如emacs,pico,vi,Notepad等。有更好的编辑器用于编写代码,但它们可能并不总是将其保存为ASCII。 ASCII是国际标准。
计算机科学就是要创造良好的抽象。有时它会成功,有时却不会成功。好的抽象都是关于呈现用户可以使用的世界观。其中一个最成功的抽象是文本编辑器。
当您编写程序并输入注释时,很难想象此信息不会存储为字符。 ASCII /文本文件实际上存储为0&1和#1。
文件存储在磁盘上,磁盘可以用某种方式表示1和0。我们只称它们为1和0,因为它也是一种抽象。无论用什么方式存储磁盘上的0和1,我们都不在乎,只要我们能够这样想它们。
实际上,ASCII文件基本上是二进制文件,因为它们存储二进制数。也就是说,ASCII文件存储0&1和#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"。也就是说,字母'然后' 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; 4'的ASCII代码。和' 9'。您可以将这些程序称为十六进制编辑器。不幸的是,这些可能不那么容易获得。编写一个读取类似十六进制对的ASCII文件的程序并不难,但随后将其转换为具有相应位模式的真正二进制文件。
也就是说,它需要一个看起来像这样的文件:
63 a0 de
并将此ASCII文件转换为以0110 0011开头的二进制文件(二进制为63)。请注意,此文件是ASCII,这意味着真正存储的是' 6',' 3','的ASCII代码。 ' (空格),' a',' 0'等等。程序可以读取此ASCII文件,然后生成相应的二进制代码并将其写入文件。
因此,ASCII文件可能包含8个字节(字符为6个,空格为2个),输出二进制文件包含3个字节,每个十六进制对一个字节。
编写二进制文件
为什么人们仍然使用二进制文件?一个原因是紧凑性。例如,假设您要编写数字100000.如果您以ASCII格式输入,则需要6个字符(即6个字节)。但是,如果将其表示为无符号二进制,则可以使用4个字节将其写出来。
ASCII很方便,因为它往往是人类可读的,但它可以占用大量空间。您可以使用二进制文件更紧凑地表示信息。
例如,您可以做的一件事是将对象保存到文件中。这是一种序列化。要将其转储到文件,请使用write()方法。通常,将指向对象的指针和用于表示对象的字节数(使用sizeof运算符来确定)传递给write()方法。然后,该方法将存储在内存中的字节转储到文件中。
然后,您可以通过使用相应的read()方法从文件中恢复信息并将其放入对象中,该方法通常采用指向对象的指针(并且它应指向已分配内存的对象,无论是否为静态或动态分配)和对象的字节数,并将文件中的字节复制到对象中。
当然,你必须小心。如果您使用两个不同的编译器,或将文件从一种机器传输到另一种机器,则此过程可能不起作用。特别地,可以不同地布置对象。这可以像endianness一样简单,或者填充可能存在问题。
这种将对象保存到文件的方式既简单又简单,但它可能不是那么便携。此外,它相当于浅拷贝。如果您的对象包含指针,它将写出文件的地址。这些地址可能完全没有意义。地址在程序运行时可能有意义,但如果您退出并重新启动,这些地址可能会发生变化。
这就是为什么有些人发明了自己的存储对象格式:增加可移植性。
但是如果你知道你不是存储包含指针的对象,并且你正在同一种计算机系统上读取文件,那么你就是在使用相同的编译器,那么应该工作。
这是人们有时喜欢写出整数,字符等而不是整个对象的一个原因。它们往往更容易携带。
ASCII文件是由ASCII字符组成的二进制文件。 ASCII字符是存储在一个字节中的7位编码。因此,ASCII文件的每个字节的最高有效位都设置为0.将ASCII文件视为一种特殊的二进制文件。
通用二进制文件使用所有8位。二进制文件的每个字节可以具有完整的256位串模式(而不是只有128位串模式的ASCII文件)。
可能有一段时间,Unicode文本文件变得更加普遍。但就目前而言,ASCII文件是文本文件的标准格式。
答案 1 :(得分:0)
二进制文件基本上是任何不是“面向行”的文件。除了实际书写字符和换行符之外的任何文件还有其他符号。
通常在文字模式下编写文件时,任何新行\n
都会转换为回车符+换行符\r\n
。
使用二进制文件作为文本文件,文件存储在磁盘而不是内存中,无法实现任何内存效率。这一切都取决于你想对文件做什么以及你希望如何格式化它。
由于您正在使用纯整数(无论int
大小是什么),使用文本或二进制文件将对性能产生相同的影响(这意味着它不会对您选择使用哪种类型产生任何影响用)。
如果您想稍后在文本编辑器中修改或读取文件,最好使用文本模式来编写文件。