百科.dev
登录
> 返回资讯列表
news_article.exe
📰

Antomic write — 临时文件+ os

Atomic writes — how tempfile + os.replace prevent corrupted JSON

2026年9月8日1 次浏览来源:Dev.to 阅读原文

如果当一个进程写入一个配置文件时断电会怎样? 或者如果Windows上的抗病毒软件短暂地锁定一个文件的中写? 如果您天真地覆盖一个文件 , 无论在中断时刻存在什么部分内容 , 磁盘上还存在什么 。 对于JSON来说,这通常意味着断开的语法——投出下一个启动,整个配置实际上都丢失了. 这篇文章走过一种防止它的标准技术:先写入临时文件,再用解剖法交换. 注意:这里"Atomic"是指一个操作要么完全完成,要么完全不发生——在状态之间没有局部的,可观察到的. 数据库交易使用的同名词的感同身受. 为什么直接覆盖是危险的 有效切入...

如果当一个进程写入一个配置文件时断电会怎样? 或者如果Windows上的抗病毒软件短暂地锁定一个文件的中写? 如果您天真地覆盖一个文件 , 无论在中断时刻存在什么部分内容 , 磁盘上还存在什么 。 对于JSON来说,这通常意味着断开的语法——投出下一个启动,整个配置实际上都丢失了. 这篇文章走过一种防止它的标准技术:先写入临时文件,再用解剖法交换. 注意:这里"Atomic"是指一个操作要么完全完成,要么完全不发生——在状态之间没有局部的,可观察到的. 数据库交易使用的同名词的感同身受. 为什么直接覆盖是危险的 有效切换文件 首先然后写新内容。 如果进程在该窗口中被中断,则文件被留空或持有不完整的内容. 原因各有不同:一个,断电,反病毒软件短暂地阻断了Windows上的文件访问,或者备份工具抓取了文件中写. 在当地开发期间,这种情况很少再生,但是在长期的生产环境中,它最终会以近乎确定性地发生. 固定:写入临时文件,然后在"核心"(The Core idea)中互换简单. 永远不要直接触摸目标文件. 首先将完整的新内容写入一个临时文件,确认该写入完全成功,并只在之后将目标文件替换为临时文件. 生成一个无相撞的临时文件名并返回其文件描述符。 这里的参数很重要: 将临时文件放入与目标文件相同的目录中,确保以下调用停留在一个文件系统中. 为什么原子 这种模式的核心是最后的召唤. Python的官方文献指出"将在Unix上成为原子操作",在Windows上也进行原子操作,只要两个路径在同一文件系统中. 在POSIX系统(英语:Linux/macOS)上,这个映射到系统调用. 在内核层面,互换目录条目是一个单一的不可分割的操作. 没有任何中间状态可以观察——从外部看,文件要么处于其前游状态,要么处于后游状态,从不介于两者之间. 在Windows上,Python 3.3+执行此功能,使一个已存在的文件被解剖处理(大致相当于用旗来调用). 由于这个属性,如果进程在.中间死亡,则只有未命名的临时文件受到影响——真实的配置文件在它之前的任何有效状态上都未受影响. 将持久性加到磁盘上,即使有原子,也有更微妙的风险: 由OS页面缓存中可能仍然有所写的内容,而不是在失去电能时在磁盘上。 在这种情况下,重名本身可以完成,但重名文件的内容可能不能反映实际写作的内容. 解决这个。 只将Python的内部缓冲器推出OS——它可能仍然坐落在OS级缓存中. 请操作系统等待数据被写入物理磁盘。 将两个步骤组合在一起,可确保临时文件的内容在时间运行前在磁盘上可以持久地进行. 写入失败后清理 如果给临时文件的写入本身在部分过程中(磁盘完整,权限出错等)失败,则从未达到,因此目标文件没有受到影响. 但半写临时文件被留在了磁盘上. 留置无人看管,这些堆积为杂乱无章,所以在失败时值得明确删除. 被巢会说明自身失败的可能性(已经删除,没有权限等). 重新提升原有的例外(),确保被调用者仍然得知写作失败. 由于消耗临时文件名并将其转换成成功的目标名称,文件通常不会停留在正常操作中。 但是在极端边缘的情况下 临时文件写完后 程序就在狭小的窗口里

> 分享: