读取二进制文件并遍历每个字节

453 投票
13 回答
1154820 浏览
提问于 2025-04-15 12:27

在Python中,我该如何读取一个二进制文件,并逐个字节地遍历这个文件呢?

13 个回答

62

如果这个文件不大,放在内存里不会有问题:

with open("filename", "rb") as f:
    bytes_read = f.read()
for b in bytes_read:
    process_byte(b)

这里的 process_byte 代表你想对传入的字节进行的某种操作。

如果你想一次处理一部分内容:

with open("filename", "rb") as f:
    bytes_read = f.read(CHUNKSIZE)
    while bytes_read:
        for b in bytes_read:
            process_byte(b)
        bytes_read = f.read(CHUNKSIZE)

with 这个语句在 Python 2.5 及以上版本中可以使用。

194

这个生成器从一个文件中读取字节,分块读取文件:

def bytes_from_file(filename, chunksize=8192):
    with open(filename, "rb") as f:
        while True:
            chunk = f.read(chunksize)
            if chunk:
                for b in chunk:
                    yield b
            else:
                break

# example:
for b in bytes_from_file('filename'):
    do_stuff_with(b)

想了解更多关于迭代器生成器的信息,可以查看Python的文档。

477

Python >= 3.8

多亏了这个叫做海象运算符 (:=),解决方案变得相当简短。我们从文件中读取bytes对象,并把它们赋值给变量byte

with open("myfile", "rb") as f:
    while (byte := f.read(1)):
        # Do stuff with byte.

Python >= 3

在旧版本的Python 3中,我们需要用一种稍微啰嗦的方法:

with open("myfile", "rb") as f:
    byte = f.read(1)
    while byte != b"":
        # Do stuff with byte.
        byte = f.read(1)

或者像benhoyt说的,跳过不等于的判断,利用b""会被认为是假的这个特点。这让代码在2.6和3.x之间可以兼容,不需要任何修改。如果你在字节模式和文本模式之间切换,这样也能省去修改条件的麻烦。

with open("myfile", "rb") as f:
    byte = f.read(1)
    while byte:
        # Do stuff with byte.
        byte = f.read(1)

Python >= 2.5

在Python 2中,情况有点不同。这里我们得到的不是字节对象,而是原始字符:

with open("myfile", "rb") as f:
    byte = f.read(1)
    while byte != "":
        # Do stuff with byte.
        byte = f.read(1)

请注意,with语句在2.5以下的Python版本中是不可用的。如果你想在2.5中使用它,你需要先导入它:

from __future__ import with_statement

在2.6中就不需要这样做了。

Python 2.4及更早版本

f = open("myfile", "rb")
try:
    byte = f.read(1)
    while byte != "":
        # Do stuff with byte.
        byte = f.read(1)
finally:
    f.close()

撰写回答