gpt4 book ai didi

python - 在众多Python文件复制功能中,如果复制被中断,哪些功能是安全的?

转载 作者:行者123 更新时间:2023-12-03 16:23:06 27 4
gpt4 key购买 nike

How do I copy a file in Python?所示,有许多文件复制功能:

  • shutil.copy
  • shutil.copy2
  • shutil.copyfile(还有shutil.copyfileobj)
  • 甚至是一个简单的方法:
    with open('sourcefile', 'rb') as f, open('destfile', 'wb') as g:
    while True:
    block = f.read(16*1024*1024) # work by blocks of 16 MB
    if not block: # EOF
    break
    g.write(block)

  • 在所有这些方法中,如果出现复制中断(例如:杀死Python进程),哪些方法是 安全?列表中的最后一个看起来不错。
    安全的意思是:如果1 GB的文件副本未100%完成(例如,在副本中间被中断,则在400MB之后),则不应在文件系统中将文件大小 报告为 1GB,它应:
  • 报告最后一个字节写入时文件的大小(例如400MB)
  • 或被删除

  • 最糟糕的情况是最终文件大小是最先写入的(内部使用 fallocateftruncate?)。如果复制被打断,这将是一个问题:通过查看文件大小,我们认为文件已正确写入。
    许多增量备份程序(我正在编码)都使用“filename + mtime + fsize”来检查文件是否必须复制或是否已经存在(当然,更好的解决方案是对SHA256源文件和目标文件,但这不是每次同步都完成,这非常耗时;请在此处移开主题)。
    因此,我想确保在复制实际文件内容之前,“复制文件”功能不会立即存储最终文件的大小(然后它可能使 fsize比较变得愚蠢)。

    注意:我问这个问题是因为,虽然 shutil.filecopy在Python 3.7和更低版本上相当简单,但请参见 source(这或多或少是上面的朴素方法),在Python 3.9上似乎要复杂得多,请参见 source,并且有许多不同之处Windows,Linux,MacOS,“fastcopy”技巧等的案例

    最佳答案

    假设在复制之前不存在destfile,那么根据您对safe的定义,朴素的方法是安全的。shutil.copyfileobj()shutil.copyfile()在排名中排名第二。
    接下来是shutils.copy(),最后是shutils.copy2()
    解释:
    保证基于应用程序请求的一致性是文件系统的工作。如果仅将X字节写入文件,则文件大小将仅占这些X字节。
    因此,可以执行像朴素方法这样的直接FS操作。
    现在,这些高级功能如何处理文件系统是一个问题。
    该API并未说明如果python在复制过程中崩溃,会发生什么情况,但这是每个人的事实上的期望,即这些函数的行为类似于Unix cp,即不要弄乱文件的大小。
    假设CPython的维护者不想破坏人们的期望,那么所有这些函数都应该按照您的定义是安全的。
    就是说,我们无法在任何地方保证AFAICT。
    但是,shutil.copyfileobj()shutil.copyfile()明确表示其API promise 不会复制元数据,因此它们不太可能尝试设置大小。shutils.copy()不会尝试设置文件大小,仅尝试设置模式,在大多数文件系统中,设置大小和模式都需要两个不同的文件系统操作,因此它仍然是安全的。shutils.copy2()表示它将复制元数据,如果您查看它的source code,则会看到它仅在复制数据后才复制元数据,因此即使这样也很安全。甚至更多,copying the metadata不会复制大小。
    因此,只有在python使用的某些内部函数尝试使用ftruncate()fallocate()或此类进行优化的情况下,这才是问题,考虑到编写系统API的人(例如python维护者)非常了解人们的期望,这是不太可能的。

    关于python - 在众多Python文件复制功能中,如果复制被中断,哪些功能是安全的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65233882/

    27 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com