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

Function _atomic_write_text

scripts/k.py:27–79  ·  view source on GitHub ↗

write-then-rename 原子写:先写到同目录的临时文件再 os.replace 重命名。 保证别的进程读 target 时只能看到完整旧内容或完整新内容,不会读到半截。 Windows 兼容:当目标文件被另一进程持 read handle(如 web server 正在 readFile) 时,os.replace 会抛 PermissionError [WinError 5]。重试 3 次(50ms 间隔)。 最终失败时**保留临时文件**让用户可手动 mv 收拾,而不是删了重写——避免数据丢失。

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

Source from the content-addressed store, hash-verified

25
26
27def _atomic_write_text(target: Path, content: str, encoding: str = "utf-8") -> None:
28 """write-then-rename 原子写:先写到同目录的临时文件再 os.replace 重命名。
29 保证别的进程读 target 时只能看到完整旧内容或完整新内容,不会读到半截。
30
31 Windows 兼容:当目标文件被另一进程持 read handle(如 web server 正在 readFile)
32 时,os.replace 会抛 PermissionError [WinError 5]。重试 3 次(50ms 间隔)。
33 最终失败时**保留临时文件**让用户可手动 mv 收拾,而不是删了重写——避免数据丢失。
34 """
35 import time as _time
36
37 target.parent.mkdir(parents=True, exist_ok=True)
38 tmp_fd, tmp_path = tempfile.mkstemp(
39 dir=str(target.parent),
40 prefix=f".{target.name}.",
41 suffix=".tmp",
42 )
43 try:
44 with os.fdopen(tmp_fd, "w", encoding=encoding, newline="") as f:
45 f.write(content)
46 except Exception:
47 # 写 tmp 都失败 → 直接清理 + 抛
48 try:
49 os.unlink(tmp_path)
50 except OSError:
51 pass
52 raise
53
54 # rename 阶段:Windows 锁竞争重试
55 last_exc: Exception | None = None
56 for attempt in range(3):
57 try:
58 os.replace(tmp_path, str(target))
59 return
60 except PermissionError as e:
61 last_exc = e
62 _time.sleep(0.05)
63 # 3 次都失败:清理 tmp(避免污染 git status),给 stderr 明确提示让用户重试
64 try:
65 os.unlink(tmp_path)
66 except OSError:
67 # 实在删不掉 → 提示用户清理路径
68 print(
69 f"[_atomic_write_text] 警告:临时文件无法清理:{tmp_path} "
70 f"(可能仍被进程持有;请重启相关进程后手动 rm)",
71 file=sys.stderr,
72 )
73 print(
74 f"[_atomic_write_text] os.replace 失败 3 次(目标 {target} 可能被另一进程持锁);"
75 f"请稍后重试,或重启占用该文件的进程",
76 file=sys.stderr,
77 )
78 if last_exc is not None:
79 raise last_exc
80
81# 让 Windows 终端也能正确输出中文
82if sys.platform == "win32":

Callers 1

annotate_sectionFunction · 0.70

Calls

no outgoing calls

Tested by

no test coverage detected