如何将原始文件系统的很大一部分复制到文件中?

2024-09-29 00:22:33 发布

您现在位置:Python中文网/ 问答频道 /正文

我在使用一个神秘的数据收集文件系统。它有一个描述文件及其在磁盘上的精确偏移量的块,所以我知道每个文件的起始字节、结束字节和字节长度。目标是从物理磁盘中获取一个文件。它们是大文件,所以性能是最重要的。你知道吗

以下是“有效”但效率很低的方法:

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复制是行不通的。(我假设)不能指定结束位置,所以复制不会停止。你知道吗

以下是一些问题,每一个问题都可以解决:

  • 是否有一个拷贝库(或用于Windows7的外部实用程序,可以与subprocess一起使用)接受开始/结束字节参数?你知道吗
  • 有没有可能创建一个copyfileobj可以使用的类文件对象,它只引用另一个类文件对象的一部分?你知道吗
  • io对象查找超过某个端点时,是否可以引发异常?你知道吗
  • 可以强制copyfileobj在驱动器的给定字节偏移量(一种“假EOF”)处自然停止吗?你知道吗

Tags: 文件对象iosrc目标字节filename磁盘
1条回答
网友
1楼 · 发布于 2024-09-29 00:22:33

显而易见的方法是只write到文件。你知道吗

copyfileobj的关键是它为您缓冲数据。如果必须将整个文件读入BytesIO,则只需缓冲BytesIO,这是毫无意义的。你知道吗

所以,只要在read上循环一个大小合适的缓冲区,从src_fwritedst_f,直到达到flength字节。你知道吗

如果你看看the ^{} source(它是从the ^{} docs链接而来的),在copyfileobj里面没有魔力;它是一个微不足道的函数。从3.6开始(我认为自从shutil被添加到2.1左右之后,它就完全没有变化……),它看起来是这样的:

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)

您可以做同样的事情,只需跟踪读取的字节并在flength处停止:

def copypartialfileobj(fsrc, fdst, size, length=16*1024):
    """copy size bytes from file-like object fsrc to file-like object fdst"""
    written = 0
    while written < size:
        buf = fsrc.read(min(length, size - written))
        if not buf:
            break
        fdst.write(buf)
        written += len(buf)

相关问题 更多 >