复制文件,但不要覆盖,不要在Python中出现TOCTTOU问题

时间:2015-05-25 23:20:59

标签: python race-condition shutil

我知道如果我想用Python复制文件但不覆盖目标,我可以使用这样的代码:

if os.path.exists(dest):
    raise Exception("Destination file exists!")
else:
    shutil.copy2(src, dest)

但世界状况可能会在我拨打os.path.exists和拨打copy2之间发生变化。是否有更优选的方式进行复制而不进行覆盖,大概是如果目标已经存在,复制操作会引发异常?

1 个答案:

答案 0 :(得分:9)

您可以使用较低级os.open,然后使用os.fdopen复制文件:

import os
import shutil

# Open the file and raise an exception if it exists
fd = os.open(filename, os.O_CREAT | os.O_EXCL | os.O_WRONLY)

# Copy the file and automatically close files at the end
with os.fdopen(fd) as f:
    with open(src_filename) as sf:
        shutil.copyfileobj(sf, f)