27 lines
1.0 KiB
Python
27 lines
1.0 KiB
Python
"""产物文件操作:以同目录临时文件复制并原子替换,避免暴露写到一半的成品。"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import shutil
|
|
import tempfile
|
|
from pathlib import Path
|
|
|
|
|
|
def atomic_copy(source: Path, target: Path) -> None:
|
|
"""保留源文件,完整复制后替换目标;失败清理临时文件并保留原目标。
|
|
|
|
临时文件与目标位于同一目录,确保 replace 不跨文件系统;关闭句柄后再
|
|
copy2/replace,兼容 Windows。原子性针对单个文件,不承诺多文件事务或
|
|
断电持久性;调用方仅在全部必需文件复制成功后登记完成并清理工作空间。
|
|
"""
|
|
target.parent.mkdir(parents=True, exist_ok=True)
|
|
with tempfile.NamedTemporaryFile(
|
|
dir=target.parent, prefix=f".{target.name}.", suffix=".tmp", delete=False
|
|
) as handle:
|
|
temporary = Path(handle.name)
|
|
try:
|
|
shutil.copy2(source, temporary)
|
|
temporary.replace(target)
|
|
finally:
|
|
temporary.unlink(missing_ok=True)
|