标题可能会更好,但无论如何。我想知道是否有任何函数可以写入文件,就像数据库的ACID属性一样。原因是,我想确保文件写入我不会搞砸并破坏文件,如果电源熄灭。
答案 0 :(得分:4)
根据您对文件和平台的具体操作,有几种选择:
如果要将blob从内存序列化到磁盘以反复维护状态(例如:dhcp leases file), 如果您使用Posix系统,则可以将数据写入临时文件,并将临时文件“重命名”到目标。在Posix兼容系统上,这保证是一个原子操作,即使文件系统是否已记录,也不应该。如果您使用的是Windows系统,则可以通过绑定使用名为MoveFileTransacted的本机函数。但这里的关键概念是,临时文件保护您的数据,如果系统重新启动最坏的情况是您的文件包含最后一次良好的数据刷新。此选项要求您在每次要记录更改时写出整个文件。在dhcp.leases文件的情况下,这不是一个很大的性能损失,更大的文件可能会更麻烦。
如果您经常阅读和编写数据,sqlite3是可行的方法 - 它支持查询组的原子提交,并拥有自己的内部日志。这里要注意的一件事是,由于锁定数据库,等待数据刷新等的开销,原子提交会变慢。
还需要考虑其他一些事项 - 如果你的文件系统是异步挂载的,那么write会显得完整,因为write()会返回,但它可能还没有被刷新到磁盘。在这种情况下,重命名可以保护您,sqlite3也可以。
如果您的文件系统是异步挂载的,则可以在写入数据之前写入数据并移动它。因此,如果您使用的是unix系统,那么安装同步可能是最安全的。那就是'人们可能会因为失败而失败'偏执狂的程度。但是,如果它是一个嵌入式系统并且它死了'如果失败我可能会失去工作'对于额外的保护也是一个很好的合理化。
答案 1 :(得分:1)
ZODB是一个符合ACID标准的数据库存储(主要是)用python写的,所以在某种意义上答案是肯定的。但我可以想象这有点矫枉过正:)
操作系统必须为您提供此功能,否则您需要实现自己的ACID合规性。例如,通过在您编写的文件中定义“记录”,并在打开/读取时,验证已写入哪些记录(这可能意味着您需要丢弃一些未完全写入的数据)。例如,ZODB通过写入记录本身的大小来结束记录来实现这一点;如果您可以阅读此大小并且匹配,则您知道该记录已完全写入。
当然,您总是需要追加记录而不是重写整个文件。
答案 2 :(得分:1)
在我看来,您的主要目标是在发生电源故障和系统崩溃时确保写入文件的完整性。这样做有几件事需要考虑:
另一种方法是使用sqlite3。
编辑:关于我的第二点,我强烈推荐这个演讲:http://www.flamingspork.com/talks/2007/06/eat_my_data.odp。这也涵盖了“原子重命名”的问题。