python - 读取/写入大型二进制文件时的首选 block 大小

标签 python file python-3.4

我需要读写巨大的二进制文件。是否有我应该一次 read() 的首选甚至最佳字节数(我称之为 BLOCK_SIZE)?

一个字节肯定太少了,而且我认为将 4 GB 读入 RAM 也不是一个好主意 - 是否存在“最佳” block 大小?或者这甚至取决于文件系统(我在 ext4 上)?我需要考虑什么?

Python's open()甚至提供了一个 buffering 参数。我是否也需要对其进行调整?

这是将 in-0.datain-1.data 这两个文件连接到 out.data 中的示例代码(在现实生活中,有更多与手头问题无关的处理)。 BLOCK_SIZE 选择等于 io.DEFAULT_BUFFER_SIZE这似乎是 buffering 的默认设置:

from pathlib import Path
from functools import partial

DATA_PATH = Path(__file__).parent / '../data/'

out_path = DATA_PATH / 'out.data'
in_paths = (DATA_PATH / 'in-0.data', DATA_PATH / 'in-1.data')

BLOCK_SIZE = 8192

def process(data):
    pass

with out_path.open('wb') as out_file:
    for in_path in in_paths:
        with in_path.open('rb') as in_file:
            for data in iter(partial(in_file.read, BLOCK_SIZE), b''):
                process(data)
                out_file.write(data)
#            while True:
#                data = in_file.read(BLOCK_SIZE)
#                if not data:
#                    break
#                process(data)
#                out_file.write(data)

最佳答案

让操作系统为您做决定。使用 mmap 模块:

https://docs.python.org/3/library/mmap.html

它使用操作系统的底层内存映射机制将文件内容映射到 RAM。

请注意,如果您使用的是 32 位 Python,则文件大小有 2GB 的限制,因此如果您决定采用这种方式,请务必使用 64 位版本。

例如:

f1 = open('input_file', 'r+b')
m1 = mmap.mmap(f1.fileno(), 0)
f2 = open('out_file', 'a+b') # out_file must be >0 bytes on windows
m2 = mmap.mmap(f2.fileno(), 0)
m2.resize(len(m1))
m2[:] = m1 # copy input_file to out_file
m2.flush() # flush results

请注意,您不必调用任何 read() 函数并决定将多少字节带入 RAM。此示例只是将一个文件复制到另一个文件,但正如您在示例中所说,您可以在两者之间进行任何需要的处理。请注意,虽然整个文件被映射到 RAM 中的地址空间,但这并不意味着它实际上已被复制到那里。它将根据操作系统的判断分段复制。

关于python - 读取/写入大型二进制文件时的首选 block 大小,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32748231/

相关文章:

python - 如何查看numpy.random.exponential的源码?

python - 根据具有特定值的行创建新数据框

c - 为什么 fopen/fgets 同时使用 mmap 和 read 系统调用来访问数据?

javascript - 从对象 dataURL 创建文件

python - 如何忽略颜色栏中的 NaN?

python - 如何创建用于 pig 拉丁和嘶嘶声翻译的代码以及同时应用它们的代码?

c - 如何在 .txt 文件 C 中搜索特定的字符串和整数并使用它们?

python - 类对象没有属性tk?

python-3.4 - Python 3.4 帮助 - 使用切片替换字符串中的字符

python-3.x - 如何使用 Ansible 安装 python3.4.3