代码之家  ›  专栏  ›  技术社区  ›  Aillyn

删除文件的任意块

  •  3
  • Aillyn  · 技术社区  · 15 年前

    说文件是这个

    ..............xxxxxxxx----------------
    

    ..............[xxxxxxxx]----------------
    

    操作后应为:

    ..............----------------
    

    3 回复  |  直到 15 年前
        1
  •  4
  •   Alex Martelli    15 年前

    最好的性能几乎总是通过写一个新版本的文件,然后让它原子地写旧版本来获得的,因为文件系统对这种顺序访问进行了强烈的优化,底层硬件也是如此(除了一些最新版本之外) SSD 能够 总是在任何时候崩溃(根据墨菲定律,它会选择最不幸的时刻;-),数据的完整性通常被认为是非常重要的(通常数据比保存它的系统更有价值——因此,“镜像”RAID解决方案以确保 丢失宝贵数据;-)。

    如果您接受这种理智的方法,一般的想法是:打开旧文件进行读取,打开新文件进行写入(创建);将N1字节从旧文件复制到新文件;然后跳过旧文件的N2字节;然后复制其余的字节;关闭两个文件;以原子方式将新文件重命名为旧文件。(Windows显然没有可以从Python中使用的“原子重命名”系统调用--为了保持完整性,在这种情况下,您需要执行三个步骤:将旧文件重命名为备份名称,将新文件重命名为旧文件,删除备份命名文件--如果在这三个非常快速的操作中的第二个操作中发生系统崩溃,只需一个重命名即可。)恢复数据完整性所需的时间)。

    with open('old.dat', 'rb') as oldf: with open('NEWold.dat', 'wb') as newf:

    对于“复制其余部分”步骤, shutil.copyfileobj 是最好的(一定要指定一个缓冲区长度,它可以很好地适应可用的RAM,但是 一个将倾向于提供更好的性能)。“跳过”这一步显然只是一个简单的步骤 seek oldf 打开以读取文件对象。为了精确地将N1字节从oldf复制到newf,Python的标准库中没有直接的支持,因此您必须自己编写,例如:

    def copyN1(oldf, newf, N1, buflen=1024*1024):
        while N1:
          newf.write(oldf.read(min(N1, buflen)))
          N1 -= buflen
    
        2
  •  0
  •   Ihor Kaharlichenko    15 年前

    我建议你 memory mapping 操作内存中的文件 它比将整个文件直接读入内存更有效。

    嗯,您必须以某种方式操纵内存中的文件内容,因为无论是在*nix中还是在Win中都没有系统调用这种操作(至少我不知道)。

        3
  •  0
  •   Borealid    15 年前

    mmap 正在删除文件。这不一定能一次把它全部读入内存。

    如果你真的想用手来做的话,选择一些块大小,做来回的读写。但是他们会杀了你。。。