考虑这个例子:
FILE* stream = fopen("my_file", "w");
fputs("hello", stream);
如果在执行 fputs() 期间断电会发生什么?
之后,我能找到大小非零但第一个字节不是“h”的“my_file”吗?如果是,它是否保证为零,或者它是否可以包含任意值?
当然,假设没有其他人接触我们的文件。
编辑:还假设目标磁盘驱动器/设备的类型能够保持足够长的功率以写入它在内部缓冲的所有数据。
POSIX 对此有什么要说的吗?有Linux吗?有窗户吗?
编辑:我不打算关注如何实现 STDIO 流 API 的细节。假设 POSIX,这就是我真正的意思:
int fd = open("my_file", O_WRONLY|O_CREAT|O_TRUNC, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);
write(fd, "hello", 5);
编辑:POSIX 将大小视为文件的元数据,因此问题可能改写为:由于上述代码,文件数据和该文件的元数据是否可以分阶段提交到磁盘?
编辑:在http://www.sqlite.org/atomiccommit.html找到这个:
7.5 具有安全附加语义的文件系统
SQLite 3.5.0 版中引入的另一个优化利用了底层磁盘的“安全附加”行为。回想一下,SQLite 假设当数据被附加到文件(特别是回滚日志)时,首先增加文件的大小,然后再写入内容。因此,如果在文件大小增加后但在写入内容之前断电,则文件将包含无效的“垃圾”数据。然而,VFS 的 xDeviceCharacteristics 方法可能表明文件系统实现了“安全附加”语义。这意味着内容是在文件大小增加之前写入的,因此不可能通过断电或系统崩溃将垃圾引入回滚日志。
这似乎至少提供了部分答案。