python循环遍历文件夹_python - 读取二进制文件并循环遍历每个

在Python中读取二进制文件并在每个字节上循环

Python 3.5中新增的是file.read1模块,该模块具有一种特殊的方法,可以将文件作为字节读入,从而允许我们迭代字节。 我认为这是一个体面的(如果快速和肮脏)答案:

import pathlib

for byte in pathlib.Path(path).read_bytes():

print(byte)

有趣的是,这是提到file.read1的唯一答案。

在Python 2中,你可能会这样做(正如Vinay Sajip也建议的那样):

with open(path, 'b') as file:

for byte in file.read():

print(byte)

如果文件可能太大而无法在内存中进行迭代,那么您可以使用带有file.read签名的file.read1函数(Python 2版本)进行特定的块化:

with open(path, 'b') as file:

callable = lambda: file.read(1024)

sentinel = bytes() # or b''

for chunk in iter(callable, sentinel):

for byte in chunk:

print(byte)

(其他几个答案提到了这一点,但很少有人提供合理的读取大小。)

大文件或缓冲/交互式阅读的最佳实践

让我们创建一个执行此操作的函数,包括Python 3.5+标准库的惯用用法:

from pathlib import Path

from functools import partial

from io import DEFAULT_BUFFER_SIZE

def file_byte_iterator(path):

"""given a path, return an iterator over the file

that lazily loads the file

"""

path = Path(path)

with path.open('rb') as file:

reader = partial(file.read1, DEFAULT_BUFFER_SIZE)

file_iterator = iter(reader, bytes())

for chunk in file_iterator:

for byte in chunk:

yield byte

请注意,我们使用file.read1. file.read块,直到它获得所请求的所有字节或EOF. file.read1允许我们避免阻塞,并且它可以因此而更快地返回。 没有其他答案也提到这一点。

演示最佳实践用法:

让我们创建一个具有兆字节(实际上是mebibyte)的伪随机数据的文件:

import random

import pathlib

path = 'pseudorandom_bytes'

pathobj = pathlib.Path(path)

pathobj.write_bytes(

bytes(random.randint(0, 255) for _ in range(2**20)))

现在让我们迭代它并在内存中实现它:

>>> l = list(file_byte_iterator(path))

>>> len(l)

1048576

我们可以检查数据的任何部分,例如,最后100个字节和前100个字节:

>>> l[-100:]

[208, 5, 156, 186, 58, 107, 24, 12, 75, 15, 1, 252, 216, 183, 235, 6, 136, 50, 222, 218, 7, 65, 234, 129, 240, 195, 165, 215, 245, 201, 222, 95, 87, 71, 232, 235, 36, 224, 190, 185, 12, 40, 131, 54, 79, 93, 210, 6, 154, 184, 82, 222, 80, 141, 117, 110, 254, 82, 29, 166, 91, 42, 232, 72, 231, 235, 33, 180, 238, 29, 61, 250, 38, 86, 120, 38, 49, 141, 17, 190, 191, 107, 95, 223, 222, 162, 116, 153, 232, 85, 100, 97, 41, 61, 219, 233, 237, 55, 246, 181]

>>> l[:100]

[28, 172, 79, 126, 36, 99, 103, 191, 146, 225, 24, 48, 113, 187, 48, 185, 31, 142, 216, 187, 27, 146, 215, 61, 111, 218, 171, 4, 160, 250, 110, 51, 128, 106, 3, 10, 116, 123, 128, 31, 73, 152, 58, 49, 184, 223, 17, 176, 166, 195, 6, 35, 206, 206, 39, 231, 89, 249, 21, 112, 168, 4, 88, 169, 215, 132, 255, 168, 129, 127, 60, 252, 244, 160, 80, 155, 246, 147, 234, 227, 157, 137, 101, 84, 115, 103, 77, 44, 84, 134, 140, 77, 224, 176, 242, 254, 171, 115, 193, 29]

不要按行迭代二进制文件

不要执行以下操作 - 这会拉出任意大小的块直到它到达换行符 - 当块太小时太慢,并且可能太大:

with open(path, 'rb') as file:

for chunk in file: # text newline iteration - not for bytes

for byte in chunk:

yield byte

以上只适用于语义上人类可读的文本文件(如纯文本,代码,标记,降价等...基本上任何ascii,utf,latin等编码)。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值