关于二进制文件的一般问题

时间:2011-03-26 17:39:28

标签: python binaryfiles binary-data

我是初学者,我在抓取二进制文件方面遇到了麻烦。当我以二进制模式(在python中)写入文件时,我只写正常文本。关于它没有任何二进制文件。我知道我的计算机上的每个文件都是二进制文件,但我无法区分我用二进制模式编写的文件和音频,视频等文件,如果我在文本编辑器中打开它们会显示为乱码。

如何创建显示为乱码的文件?你能举个像这样创建的小文件的例子,最好是在python中吗?

我有一种感觉,我问的是一个非常愚蠢的问题,但我只是要问它。谷歌搜索并没有帮助我。

6 个答案:

答案 0 :(得分:4)

以下是您问题的字面答案:

import struct
with open('gibberish.bin', 'wb') as f:
    f.write(struct.pack('<4d', 3.14159, 42.0, 123.456, 987.654))

将4个浮点数打包成二进制格式(little-endian IEEE 756 64位浮点数。)

这是你需要知道的(部分):

以二进制模式读取和写入文件不会对您读取或写入的数据进行转换。在文本模式下,以及与Unicode之间的任何解码/编码,您读取或写入的数据将根据“文本文件”的平台约定进行转换。

Unix / Linux / Mac OS X:没有变化

较旧的Mac:行分隔符为\r,已更改为/从Python标准\n

Windows:行分隔符为\r\n,已更改为/ \n。另外(鲜为人知的事实),Ctrl-Z又名\x1a被解释为文件结束,这是一种从CP/M继承的约定,它将文件大小记录为使用的128字节扇区的数量。

答案 1 :(得分:4)

  

当我以二进制模式(在python中)写入文件时,我只写正常文本。

升级到Python 3.x时,您必须更改方法:

>>> f = open(filename, 'wb')
>>> f.write("Hello, world!\n")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: must be bytes or buffer, not str
>>> f.write(b"Hello, world!\n")
14

但你的问题并不是关于二进制文件。这是关于str

在Python 2.x中,str byte 序列,具有重载含义:

  • 非Unicode字符串或
  • 原始二进制数据(如图像中的像素)。

如果你打印后者,就像前者一样,你会得到胡言乱语。

Python 3.x通过为二进制数据引入单独的bytes类型来消除这种双重含义,将str明确地保留为文本字符串(并使其成为Unicode)。

答案 2 :(得分:3)

所谓的“文本”文件只是遵循某些约定的文件:字节通常是所有可能字节的子集,通常是ASCII或Unicode值,并且被组织成带有“行终止符”的“行”。标准行终止符因平台而异 - Unix使用\n,Mac \r和Windows \r\n - 因此部分约定是动态翻译它们。这适用于文本文件,但会破坏其他类型的文件,因为声音文件中的0x0a\n)字节不能很好地转换为0x0d 0x0a\r\n)。当然,如果你只使用Unix,那就不会出现了。

在Python 3中,所有字符串都是Unicode,并且将文件作为文本打开意味着您必须读取和写入Unicode字符串,并且可能指定编码(默认为UTF-8)。将文件作为二进制文件打开意味着您必须使用bytes个对象,这些对象是8位字节的简单列表,不会被编码。

这是否澄清了事情?

答案 3 :(得分:2)

通常在尝试编码对象时创建二进制文件。例如,您可能有一个Person对象,其属性包括Name,Age,Height。如果您要将此文件写为文本以便以后可以回读,则可能会输出如下内容:

Name:Ralph
Age:25
Height:5'6"

但是你可以用二进制来更紧凑地表示它。在二进制文件中,您可能只是一个接一个地输出名称,年龄和高度,并且您必须以完全相同的顺序读回它们,因为您不再具有这些分隔符。在这种情况下,您的字符串必须使用Ralph\0之类的编码。 \0是空字符,因此它知道字符串的结束位置。

25可以用文本/ ASCII中的两个字符表示,但是如果你尝试并排放两个数字,比如25和26,那么你会得到2526而你不知道在哪里一个结束,另一个结束。这些数字实际上是整数,由4个字节表示。当你把文件写成二进制文件时,你会写出所有4个字节,即使最左边的位都是0.这样它总能确切知道读取多少。等等......

这就是“二进制文件”看起来像乱七八糟的原因,因为他们已经获得了所有这些额外的信息。

要生成这些文件,您必须像John Machin建议的那样对数据进行编码或“打包”。

答案 4 :(得分:0)

也许您正在二进制文件中发送字符串,而您的计算机可以对其进行解码并显示给您?尝试用随机字节写一个文件。或者您可以向我们展示您的代码,以便我们了解问题。

答案 5 :(得分:0)

我建议使用Python的编解码器模块来编写文本文件(它允许您设置相关的字符集/编码)。对于编写二进制文件,请使用标准file()方法。在Windows上,您可能需要使用'wb'或'rb'来表示二进制模式(在Unix上无关紧要)。