python - 删除文件的任意 block

标签 python c file-io

给定开始和结束偏移量,删除文件的任意 block 的最有效方法是什么?我更喜欢使用 Python,但如果必须的话,我可以回退到 C。

说文件是这个

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

我想删除其中的一部分:

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

运行后应该变成:

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

将整个东西读入内存并在内存中操作它不是一个可行的选择。

最佳答案

最好的性能几乎总是通过写入文件的新版本然后让它自动写入旧版本来获得,因为文件系统针对这种顺序访问进行了强烈优化,底层硬件也是如此(可能有异常(exception)一些最新的 SSD,但即便如此,这也是一个不确定的提议)。此外,这可以避免在系统崩溃的情况下随时破坏数据——您留下的文件要么是完整的旧版本,要么是新版本。由于每个系统可能总是在任何时候崩溃(根据墨菲定律,它会选择最不幸的时刻;-),数据的完整性通常被认为非常重要(通常数据比系统更有值(value)它保存在上面——因此,“镜像”RAID 解决方案以确保防止磁盘崩溃而丢失宝贵的数据;-)。

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

当然,N1 和 N2 是两个参数,说明删除的片段从哪里开始,以及它有多长。对于打开文件的部分,with open('old.dat', 'rb') as oldf:with open('NEWold.dat', 'wb') as newf : 相互嵌套的语句显然是最好的(当然,重命名步骤之前的其余代码必须嵌套在这两个语句中)。

对于“复制其余部分”步骤,shutil.copyfileobj是最好的(一定要指定一个可以轻松适应可用 RAM 的缓冲区长度,但是往往会提供更好的性能)。 “跳过”步骤显然只是对 oldf 打开以供读取的文件对象的 seek。对于从 oldf 复制 N1 个字节到 newf,Python 的标准库没有直接支持,所以你必须自己写,例如:

def copyN1(oldf, newf, N1, buflen=1024*1024):
    while N1:
      newf.write(oldf.read(min(N1, buflen)))
      N1 -= buflen

关于python - 删除文件的任意 block ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3539517/

相关文章:

python - 使用 pandas 在 python 中读取 csv 文件时出错

java - Jython与ortool库

python - 如何针对 Google Cloud SQL 运行 Django 管理命令

谁能解释什么是 Windows HAL 以及它的用途?

performance - 探索系统中哪些文件被大量使用

python - 字典中哪些键值没有更新?

c - BrainFuck 实现问题 :

c - 无法使用套接字写入流

go - 并发地逐行读取文件

java - 如何在 Java 中读取 Excel 单元格中的字母数字值?