直接 writeFile('config.json', ...) 有个小风险:进程崩在写入中间时,文件可能只剩半截。Node 里也可以走临时文件 + rename 这条路,临时文件放同目录,最后替换会更稳一点。
环境:Node.js 20+,Linux/macOS/Windows,只用内置模块。保存为 atomic-json.mjs:
import { mkdtemp, writeFile, rename, rm, readFile } from 'node:fs/promises';
import { dirname, join } from 'node:path';
import { tmpdir } from 'node:os';
async function writeJsonAtomic(path, value) {
const dir = dirname(path);
const tempDir = await mkdtemp(join(dir, '.tmp-write-'));
const tempFile = join(tempDir, 'data.json');
try {
await writeFile(tempFile, JSON.stringify(value, null, 2) + '\n', 'utf8');
await rename(tempFile, path);
} finally {
await rm(tempDir, { recursive: true, force: true });
}
}
const file = join(tmpdir(), 'node-atomic-json-demo.json');
await writeJsonAtomic(file, { version: 1, enabled: true });
console.log(await readFile(file, 'utf8'));
运行:
node atomic-json.mjs
如果目标目录可能不存在,先 mkdir(dir, { recursive: true })。另外跨磁盘移动就不是同一个原子替换语义了,所以临时文件最好一直放在目标文件同目录。