我在使用一个神秘的数据收集文件系统。它有一个描述文件及其在磁盘上的精确偏移量的块,所以我知道每个文件的起始字节、结束字节和字节长度。目标是从物理磁盘中获取一个文件。它们是大文件,所以性能是最重要的。你知道吗
以下是“有效”但效率很低的方法:
import shutil, io
def start_copy(startpos, endpos, filename="C:\\out.bin"):
with open(r"\\.\PhysicalDrive1", 'rb') as src_f:
src_f.seek(startpos)
flength = endpos - startpos
print("Starting copy of "+filename+" ("+str(flength)+"B)")
with open(filename, 'wb') as dst_f:
shutil.copyfileobj( io.BytesIO(src_f.read(flength)), dst_f )
print("Finished copy of "+filename)
这很慢:io.BytesIO(src_f.read(flength))
从技术上讲是可行的,但它会在写入目标文件之前将整个文件读入内存。所以这比它应该花的时间要长得多。你知道吗
直接用dst_f
复制是行不通的。(我假设)不能指定结束位置,所以复制不会停止。你知道吗
以下是一些问题,每一个问题都可以解决:
subprocess
一起使用)接受开始/结束字节参数?你知道吗copyfileobj
可以使用的类文件对象,它只引用另一个类文件对象的一部分?你知道吗io
对象查找超过某个端点时,是否可以引发异常?你知道吗copyfileobj
在驱动器的给定字节偏移量(一种“假EOF”)处自然停止吗?你知道吗
显而易见的方法是只
write
到文件。你知道吗copyfileobj
的关键是它为您缓冲数据。如果必须将整个文件读入BytesIO
,则只需缓冲BytesIO
,这是毫无意义的。你知道吗所以,只要在
read
上循环一个大小合适的缓冲区,从src_f
和write
到dst_f
,直到达到flength
字节。你知道吗如果你看看the ^{} source (它是从the ^{} docs 链接而来的),在
copyfileobj
里面没有魔力;它是一个微不足道的函数。从3.6开始(我认为自从shutil
被添加到2.1左右之后,它就完全没有变化……),它看起来是这样的:您可以做同样的事情,只需跟踪读取的字节并在
flength
处停止:相关问题 更多 >
编程相关推荐