使用itertools.chain
很容易拼接可迭代对象:
from itertools import chain
def read_by_chunks(file_objects, block_size=1024):
readers = (iter(lambda f=f: f.read(block_size), '') for f in file_objects)
return chain.from_iterable(readers)
您可以执行以下操作:
for chunk in read_by_chunks([f1, f2, f3, f4], 4096):
handle(chunk)
按顺序处理文件,同时按4096
字节块读取。
如果您需要提供一个具有 read
方法的对象,因为某些其他函数期望这样做,您可以编写一个非常简单的包装器:
class ConcatFiles(object):
def __init__(self, files, block_size):
self._reader = read_by_chunks(files, block_size)
def __iter__(self):
return self._reader
def read(self):
return next(self._reader, '')
然而,这种方法只使用固定的块大小。可以通过以下方式支持read
函数的block_size
参数:
def read(self, block_size=None):
block_size = block_size or self._block_size
total_read = 0
chunks = []
for chunk in self._reader:
chunks.append(chunk)
total_read += len(chunk)
if total_read > block_size:
contents = ''.join(chunks)
self._reader = chain([contents[block_size:]], self._reader)
return contents[:block_size]
return ''.join(chunks)
注意:如果您正在以二进制模式阅读,请用空字节
b''
替换代码中的空字符串
''
。