读/写大二进制文件时的首选块大小

hir*_*ist 7 python file python-3.4

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

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

Pythonopen()甚至提供了一个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)
Run Code Online (Sandbox Code Playgroud)

Cha*_*edy 6

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

https://docs.python.org/3.4/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
Run Code Online (Sandbox Code Playgroud)

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