使用Python进行简单的文件复制通常是这样的:
def copyfileobj(fsrc, fdst, length=16*1024):
"""copy data from file-like object fsrc to file-like object fdst"""
while 1:
buf = fsrc.read(length)
if not buf:
break
fdst.write(buf)
(顺便说一下,这段代码片段来自shutil.py)。
不幸的是,在我的特殊用例(涉及线程和非常大的缓冲区)中,这种方式有缺点(斜体部分后添加)。首先,它意味着每次调用read()时都会分配一个新的内存块,并且当buf在下一次迭代中被覆盖时,这个内存将被释放,只为了再次为同样的目的分配新的内存。这可能会减慢整个过程并对主机造成不必要的负载。
为了避免这种情况,我正在使用file.readinto()方法,不幸的是,它被记录为已弃用并且“不要使用”:
def copyfileobj(fsrc, fdst, length=16*1024):
"""copy data from file-like object fsrc to file-like object fdst"""
buffer = array.array('c')
buffer.fromstring('-' * length)
while True:
count = fsrc.readinto(buffer)
if count == 0:
break
if count != len(buffer):
fdst.write(buffer.toString()[:count])
else:
buf.tofile(fdst)
我的解决方案可行,但也存在两个缺点:首先,不建议使用readinto()方法,因为文档中可能会有所更改。其次,使用readinto()方法时,我无法决定要读取多少字节到缓冲区中,而使用buffer.tofile()方法时,我也无法决定要写入多少字节,因此需要对最后一个块进行繁琐的特殊处理(这也是不必要的昂贵操作)。
我已经尝试过使用array.array.fromfile()方法,但它不能用于读取“所有内容”(读取后抛出EOFError并不返回已处理项的数量)。此外,它也无法解决结束特殊情况的问题。
是否有一种正确的方法来实现我想要做的事情?也许我只是忽略了一个简单的缓冲区类或类似的东西,可以满足我的需求。