MCPcopy Create free account
hub / github.com/Qinbf/groundmap / _atomic_write_text

Function _atomic_write_text

scripts/convert.py:26–73  ·  view source on GitHub ↗

write-then-rename 原子写:先写到同目录的临时文件再 os.replace 重命名。 保证别的进程读 target 时只能看到完整旧内容或完整新内容,不会读到半截。 Windows 兼容:目标文件被另一进程持 read handle 时 os.replace 抛 PermissionError, 重试 3 次(50ms 间隔);最终失败保留 tmp 文件供手动收拾。

(target: Path, content: str, encoding: str = "utf-8")

Source from the content-addressed store, hash-verified

24
25
26def _atomic_write_text(target: Path, content: str, encoding: str = "utf-8") -> None:
27 """write-then-rename 原子写:先写到同目录的临时文件再 os.replace 重命名。
28 保证别的进程读 target 时只能看到完整旧内容或完整新内容,不会读到半截。
29
30 Windows 兼容:目标文件被另一进程持 read handle 时 os.replace 抛 PermissionError,
31 重试 3 次(50ms 间隔);最终失败保留 tmp 文件供手动收拾。
32 """
33 import time as _time
34
35 target.parent.mkdir(parents=True, exist_ok=True)
36 tmp_fd, tmp_path = tempfile.mkstemp(
37 dir=str(target.parent),
38 prefix=f".{target.name}.",
39 suffix=".tmp",
40 )
41 try:
42 with os.fdopen(tmp_fd, "w", encoding=encoding, newline="") as f:
43 f.write(content)
44 except Exception:
45 try:
46 os.unlink(tmp_path)
47 except OSError:
48 pass
49 raise
50
51 last_exc: Exception | None = None
52 for _ in range(3):
53 try:
54 os.replace(tmp_path, str(target))
55 return
56 except PermissionError as e:
57 last_exc = e
58 _time.sleep(0.05)
59 # 3 次都失败:清理 tmp 避免污染 git status;给 stderr 提示重试
60 try:
61 os.unlink(tmp_path)
62 except OSError:
63 print(
64 f"[_atomic_write_text] 警告:临时文件无法清理:{tmp_path}",
65 file=sys.stderr,
66 )
67 print(
68 f"[_atomic_write_text] os.replace 失败 3 次(目标 {target} 可能被另一进程持锁);"
69 f"请稍后重试",
70 file=sys.stderr,
71 )
72 if last_exc is not None:
73 raise last_exc
74
75try:
76 from markitdown import MarkItDown

Callers 1

convert_fileFunction · 0.70

Calls

no outgoing calls

Tested by

no test coverage detected