强大的原子文件复制

时间:2017-04-13 08:57:00

标签: python-3.x atomic file-copying

我目前有

def _atomic_copyfile(src, dst, overwrite):
    with tempfile.NamedTemporaryFile(dir=os.path.dirname(dst),
                                     delete=False) as tmp_h:
        with open(src, 'rb') as src_fd:
            shutil.copyfileobj(fsrc=src_fd,
                               fdst=tmp_h)
    if overwrite:
        # works both on Windows and Linux from Python 3.3+, os.rename raises an
        # exception on Windows if the file exists
        os.replace(src=tmp_h.name,
                   dst=dst)
    else:
        if not os.path.exists(dst):
            os.rename(src=tmp_h.name,
                      dst=dst)

如果抛出异常或捕获到信号,如何自动删除临时文件tmp_h

请注意,我无法使用delete=True,因为临时文件已重命名。

1 个答案:

答案 0 :(得分:0)

应该做什么(我通常不会毫无例外地使用try/except:,但在这种情况下它适用,也许你想在except中添加消息,追溯等等。情况下):

def _atomic_copyfile(src, dst, overwrite):
    try:
       with tempfile.NamedTemporaryFile(dir=os.path.dirname(dst),
                                       delete=False) as tmp_h:
       # your current code
    except:
        # maybe print something here to notify that an error occured
        # instead of masking it
        pass
    finally:
        try:
           os.remove(tmp_h.name)
        except:
           pass

finally部分中的代码尝试删除该文件。如果失败,请捕获异常并不执行任何操作(例如,如果文件不存在或已重命名,或者甚至:tmp_h变量尚不存在)

当然,即使文件已经存在,

os.remove也可能失败,但不太可能,因为你已经离开with上下文,文件已经关闭。