Python如何从文件中读取原始二进制数据?(音频/视频/文本)

10
我想读取文件的原始二进制并将其放入字符串中。目前,我正在使用“rb”标志打开文件并打印字节,但它显示为ASCII字符(对于文本而言,对于视频和音频文件则会出现符号和乱码)。如果可能,我想要得到原始的0和1。这也需要适用于音频和视频文件,所以简单地转换ASCII为二进制不是一个选项。
with open(filePath, "rb") as file:
    byte = file.read(1)
    print byte

1
可能是 https://dev59.com/LXNA5IYBdhLWcg3wQ7Yw 的重复问题。 - Chris Noreikis
不是真的。他在这里问的比另一个帖子要多。尽管他所问的可能看起来很奇怪... - Alexander Tobias Bockstaller
1
https://dev59.com/kFPTa4cB1Zd3GeqPlKaI - Navneet
2
你正在将二进制的0和1从文件中读入一个字符型字符串。尝试使用 print bin(ord(byte))。当参数是一个8位字符型字符串时,ord()函数返回字节的整数值。最后,bin()函数将整数转换为由0和1字符组成的二进制字符串,以带有“0b”前缀的形式进行打印,因此你将看到类似于0b1100001的输出。 - martineau
2个回答

10
您所读的确实是您“二进制”文件的“原始二进制”内容。尽管看起来很奇怪,但二进制数据并不是“0和1”,而是二进制“字”(也称为字节,参见http://en.wikipedia.org/wiki/Byte),它们具有整数(十进制)值,并且可以被解释为ASCII字符,或者作为整数(这是通常执行二进制操作的方式),或者作为十六进制数字。就其价值而言,“文本”实际上也是“原始二进制数据”。
要获取“二进制”表示,您可以在此处查看:将二进制转换为ASCII码和反之亦然,但这并不会给您比您实际拥有的更多的“原始二进制数据”...
现在的问题是:为什么您确切地想要这些数据作为“0和1”呢?

1
为了更加清晰明了,raw_binary_data = open(filename, "rb").read()与包含ASCII字符'0'、'1'的“01”字符串无关,这些字符串代表二进制数字系统中的数据(基于2的位置表示法的基数为2)。例如:b'\x0d'[0] == 0x0d == 13 == 0b1101 == int('1101', 2)(在Python 2中使用ord('\x0d')),但是b'\x0d' != b'1101'len(b'\x0d') == 1len(b'1101') == 4),而b'1101' == b'\x31\x31\x30\x31' - jfs

9

要获取二进制表示,我认为你需要导入binascii,然后执行以下操作:

byte = f.read(1)
binary_string = bin(int(binascii.hexlify(byte), 16))[2:].zfill(8)

或者,分解为以下几部分:
import binascii


filePath = "mysong.mp3"
file = open(filePath, "rb")
with file:
    byte = file.read(1)
    hexadecimal = binascii.hexlify(byte)
    decimal = int(hexadecimal, 16)
    binary = bin(decimal)[2:].zfill(8)
    print("hex: %s, decimal: %s, binary: %s" % (hexadecimal, decimal, binary))

将输出:

hex: 64, decimal: 100, binary: 01100100

请注意:OP应该理解“原始数据”和“二进制表示”的区别。 - bruno desthuilliers
1
这里不需要使用binascii。当处理1个字节时,我们可以使用ord()获取整数序号,然后使用hex()或bin()进行转换。但对于多字节值,binascii.hexlify()可能很方便,因为它可以一次性转换整个字节字符串。 - wombatonfire

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接