我正在编写JSON文件。这意味着对于每个'{'
字符,都有一个相应的'}'
,文件中的最后一个字节是'}'
。写入按顺序进行。没有浑浊。因此,如果对文件的写入以某种方式中断,我希望有一个无效的 JSON 文件。
现在,假设的文件系统可能会决定不按顺序刷新我的字节。这意味着,如果在写入过程中发生断电,在刷新所有内容之前,我可以得到一个不包含我想要的数据的有效 JSON。我可以"xxx"
字符串,而不是"yyy"
,或者数字末尾缺少数字。
这样的文件系统是否存在?我可以依靠这样一个事实,即如果文件有效,那么它保证是完整的吗?
编辑:此问题适用于数据如果缺少最后一个字节则无效的情况。JSON在这里是说明性的。技术上42342
是一个有效的 JSON,如果不完整,则无法验证。
文件系统可能会乱排页面的原因有多种:
- 该页面包含来自 2 个文件的数据,另一个文件正在刷新到磁盘。
- 该页面位于进程的工作集之外(因此不值得缓存(,操作系统需要内存用于其他目的。 文件系统
- 是分布式的,例如OrangeFS或Andrew文件系统,并且按照非常不同的实现规则进行。
- 文件系统 NFS 面向一组更复杂的分布式异构设备,其中某些写入是完全同步的,而应用程序并不明智。
它不仅是文件系统,还有底层设备。
- 块设备可能会进行缓冲,直到文件系统实际需要完全刷新,并以它认为正确的任何顺序刷新它(因为它不知道文件的概念(。
- 块设备可以条带化 (RAID 0(,以便一个设备可以先于另一个设备刷新。
也就是说,崩溃后不太可能像xxx
那样丢失 3 个字节。它更有可能遇到块丢失,例如 4096 字节的倍数。
事实是,大多数文件系统几乎不保证崩溃期间写入的数据(与元数据相反(的完整性。
当需要原子性时,应用程序通常做的是利用rename(2)
或其等效项:
- 写入临时文件,例如使用 POSIX
write(2)
。 - 例如,用 POSIX
fsync(2)
刷新文件并关闭它。 - 将文件重命名为目标名称,例如使用 POSIX
rename(2)
。
我知道所有正在使用的 POSIX 文件系统都以崩溃安全的方式实现 POSIX 重命名,我认为 NTFS 也是如此。
但这显然不是POSIX的严格要求。由于您正在编写新文件,因此这不是一个问题,但是如果您想变得更加偏执,则可以添加另一个步骤:
- 删除临时文件(如果错误不存在,请忽略该错误(。