Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 关于二进制文件的一般问题_Python_Binaryfiles_Binary Data - Fatal编程技术网

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

Python 关于二进制文件的一般问题,python,binaryfiles,binary-data,Python,Binaryfiles,Binary Data,我是一个初学者,在掌握二进制文件方面有困难。当我以二进制模式(在python中)写入文件时,我只写普通文本。这件事没有什么二元性。我知道我电脑上的每个文件都是二进制文件,但我很难区分我以二进制模式编写的文件和音频、视频等文件,如果我在文本编辑器中打开它们,它们会显示为乱码 显示为胡言乱语的文件是如何创建的?请给出一个这样创建的小文件的示例,最好是用python创建的 我有一种感觉,我在问一个非常愚蠢的问题,但我不得不问它。谷歌搜索对我没有帮助。也许你正在二进制文件中发送字符串,你的计算机可以解码

我是一个初学者,在掌握二进制文件方面有困难。当我以二进制模式(在python中)写入文件时,我只写普通文本。这件事没有什么二元性。我知道我电脑上的每个文件都是二进制文件,但我很难区分我以二进制模式编写的文件和音频、视频等文件,如果我在文本编辑器中打开它们,它们会显示为乱码

显示为胡言乱语的文件是如何创建的?请给出一个这样创建的小文件的示例,最好是用python创建的


我有一种感觉,我在问一个非常愚蠢的问题,但我不得不问它。谷歌搜索对我没有帮助。

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

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

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

import struct
with open('gibberish.bin', 'wb') as f:
    f.write(struct.pack('<4d', 3.14159, 42.0, 123.456, 987.654))
导入结构
以open('gibberish.bin','wb')作为f:
f、 写入(结构包('
当我以二进制模式(在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
>f=open(文件名'wb')
>>>f.写(“你好,世界!\n”)
回溯(最近一次呼叫最后一次):
文件“”,第1行,在
TypeError:必须是字节或缓冲区,而不是str
>>>f.写(b“你好,世界!\n”)
14
但你的问题不是关于二进制文件,而是关于
str

在Python2.x中,
str
是一个具有重载含义的字节序列:

  • 非Unicode字符串,或
  • 原始二进制数据(如图像中的像素)
如果你像打印前者一样打印后者,你就会胡言乱语

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

所谓的“文本”文件只是遵循某些约定的文件:字节通常是所有可能字节的子集,通常是ASCII或Unicode值,并用“行终止符”组织成“行”。标准的行终止符因平台而异-Unix使用
\n
、Mac
\r
和Windows
\r\n
-因此部分约定是动态翻译这些行终止符。这对文本文件很有效,但会对其他类型的文件造成冲击,因为
0x0a
\n
)声音文件中的字节或其他内容转换为
0x0d
0x0a
\r\n
)不太合适。当然,如果您只使用过Unix,就不会出现这种情况

在Python3中,所有字符串都是Unicode,以文本形式打开文件意味着您必须读写Unicode字符串,可能还需要指定编码(默认为UTF-8)。以二进制形式打开文件意味着您必须使用
字节
对象,这些对象是8位字节的简单列表,不需要编码


这说明问题了吗?

二进制文件通常是在您尝试对对象进行编码时创建的。例如,您可能有一个具有名称、年龄、高度等属性的Person对象。如果要将此文件作为文本写入以便以后可以读回,您可能会输出以下内容:

Name:Ralph
Age:25
Height:5'6"
但是您可以用二进制更简洁地表示它。在二进制中,您可能只需依次输出名称、年龄和高度,并且您必须以完全相同的顺序重新读取它们,因为您不再有这些分隔符。在这种情况下,您的字符串必须用类似
Ralph\0
的代码进行编码。
\0
是空字符,因此它知道字符串的结束位置

25
在text/ASCII中可以仅表示为2个字符,但如果您尝试将两个数字并排放置,例如25和26,您将得到2526,您将不知道一个数字的结束和下一个数字的开始。这些数字实际上是整数,由4个字节表示。当您以二进制形式编写文件时,您将写出所有4个字节,如even如果最左边的位都是0,那么它总是知道要读多少,以此类推

这就是为什么“二进制文件”看起来像jibberish,因为它们包含了所有这些额外的信息


要生成这些文件,你必须像约翰·梅钦建议的那样对数据进行编码或“打包”。

你计算机上的每个文件都不是二进制的。@Rafe Ketterr:你的意思是“不是你计算机上的每个文件都是二进制的”?约翰:是的,这是表达我意思的另一种方式。我说的有点含糊不清,我承认:(您计算机上的每个文件都是二进制文件。其中一些文件碰巧包含编码文本。@Rafe:错。“每个X不是Y”!=“不是每个X都是Y”。您所说的并不含糊。如何使用随机字节写入文件?我所做的就是以二进制模式打开文件(打开(文件,'wb'))。我想我是在给它写文本。你是说用pickle模块之类的东西来写文件吗?@我知道你在尝试这样写:file.write(“toto”)在这种情况下,python将为您的文本编写代码,您的计算机可以读取它。如果我要编写原始二进制数据,如图像中的像素,我将如何编写?我不是说使用PIL或图像库,而是像您所说的一般编写二进制数据。您将其存储在
str
(2.x)或
字节
(3.x)中对象。您可以使用
\x
转义符来表示不可打印的字符,例如,
yellow='\xFF\xFF\x00'
。我运行了该代码,是的,它确实显示为“胡言乱语”,但我仍然感到困惑。该代码做了什么?我在python文档中查找了结构模块,但无法取消