在 Python 中读取和解释二进制文件中的数据

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3943149/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-18 13:27:54  来源:igfitidea点击:

Reading and interpreting data from a binary file in Python

pythonbinarybitwise-operators

提问by dubbaluga

I want to read a file byte by byte and check if the last bit of each byte is set:

我想逐字节读取文件并检查是否设置了每个字节的最后一位:

#!/usr/bin/python

def main():
    fh = open('/tmp/test.txt', 'rb')
    try:
        byte = fh.read(1)
        while byte != "":
            if (int(byte,16) & 0x01) is 0x01:
                print 1
            else:
                print 0
            byte = fh.read(1)
    finally:
        fh.close

    fh.close()

if __name__ == "__main__":
        main()

The error I get is:

我得到的错误是:

Traceback (most recent call last):
  File "./mini_01.py", line 21, in <module>
    main()
  File "./mini_01.py", line 10, in main
    if (int(byte,16) & 0x01) is 0x01:
ValueError: invalid literal for int() with base 16: '\xaf'

Anyone an idea? I didn't succeed using the struct and the binascii modules.

任何人的想法?我没有成功使用 struct 和 binascii 模块。

采纳答案by nmichaels

You want to use ordinstead of int:

你想使用ord而不是int

if (ord(byte) & 0x01) == 0x01:

回答by Scott Griffiths

Try using the bytearraytype (Python 2.6 and later), it's much better suited to dealing with byte data. Your tryblock would be just:

尝试使用bytearray类型(Python 2.6 及更高版本),它更适合处理字节数据。您的try块将只是:

ba = bytearray(fh.read())
for byte in ba:
    print byte & 1

or to create a list of results:

或创建结果列表:

low_bit_list = [byte & 1 for byte in bytearray(fh.read())]

This works because when you index a bytearrayyou just get back an integer (0-255), whereas if you just read a byte from the file you get back a single character string and so need to use ordto convert it to an integer.

这是有效的,因为当您索引 a 时,bytearray您只会返回一个整数(0-255),而如果您只是从文件中读取一个字节,则会返回一个单个字符串,因此需要使用ord将其转换为整数。



If your file is too big to comfortably hold in memory (though I'm guessing it isn't) then an mmapcould be used to create the bytearrayfrom a buffer:

如果您的文件太大而无法舒适地保存在内存中(尽管我猜它不是)那么mmap可以使用an来bytearray从缓冲区创建:

import mmap
m = mmap.mmap(fh.fileno(), 0, access=mmap.ACCESS_READ)
ba = bytearray(m)

回答by tzot

One way:

单程:

import array

filebytes= array.array('B')
filebytes.fromfile(open("/tmp/test.txt", "rb"))
if all(i & 1 for i in filebytes):
    # all file bytes are odd

Another way:

其它的办法:

fobj= open("/tmp/test.txt", "rb")

try:
    import functools
except ImportError:
    bytereader= lambda: fobj.read(1)
else:
    bytereader= functools.partial(fobj.read, 1)

if all(ord(byte) & 1 for byte in iter(bytereader, '')):
    # all bytes are odd
fobj.close()