36 lines
1.1 KiB
Python
36 lines
1.1 KiB
Python
"""JSON 파일을 안전하게 저장하는 공통 유틸리티."""
|
|
|
|
import json
|
|
import os
|
|
import tempfile
|
|
from pathlib import Path
|
|
from typing import Any
|
|
|
|
|
|
def atomic_write_json(path: str | Path, value: Any) -> None:
|
|
"""같은 디렉터리의 임시 파일을 교체하여 JSON을 원자적으로 저장한다."""
|
|
target = Path(path)
|
|
target.parent.mkdir(parents=True, exist_ok=True)
|
|
temporary_path: Path | None = None
|
|
|
|
try:
|
|
with tempfile.NamedTemporaryFile(
|
|
mode="w",
|
|
encoding="utf-8",
|
|
dir=target.parent,
|
|
prefix=f".{target.name}.",
|
|
suffix=".tmp",
|
|
delete=False,
|
|
) as temporary:
|
|
json.dump(value, temporary, ensure_ascii=False, indent=2)
|
|
temporary.write("\n")
|
|
temporary.flush()
|
|
os.fsync(temporary.fileno())
|
|
temporary_path = Path(temporary.name)
|
|
|
|
os.replace(temporary_path, target)
|
|
temporary_path = None
|
|
finally:
|
|
if temporary_path is not None:
|
|
temporary_path.unlink(missing_ok=True)
|