我有一个应用程序,它使用硬链接对两个目录的内容进行重复数据删除。我想保护这些代码免于崩溃,这样回溯永远不会导致数据丢失。
目前,代码看起来像这样:
import os
import tempfile
for path_a, path_b in paths_to_dedupe:
handle, tmp = tempfile.mkstemp(dir=os.path.dirname(path_a))
handle.close()
os.remove(tmp)
os.link(path_a, tmp)
os.rename(tmp, path_b)
此代码的问题是对os.remove()的调用 - 这使得对mkstemp的调用不再完全安全(因为可以创建另一个同名的临时文件,但不太可能)。
有更安全的方法吗?
我考虑过复制和修改tempfile._mkstemp_inner()
,因此它会运行_os.link
而不是_os.open
。
答案 0 :(得分:1)
最简单的方法是循环,直到os.link
成功:
while True:
handle, tmp = tempfile.mkstemp(…)
os.close(handle)
os.remove(tmp)
try:
os.link(path_a, tmp)
except OSError as e:
if e.errno == 17: # file exists
continue
raise
break
在这种情况下,使用tempfile
没有任何实际好处(即,因为您不需要以打开的文件结尾),所以您可以自己做:
while True:
tmp = path_b + "-temp-%s" %(os.urandom(8).encode("hex"), )
try:
os.link(path_a, tmp)
except OSError as e:
if e.errno == 17: # file exists
continue
raise
break
当然,你会想要在整个事情周围抛出一个try/finally
,以确保在将它移动到位之前你不会意外地将临时文件留在周围:)