2

考虑这个例子:

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 方法可能表明文件系统实现了“安全附加”语义。这意味着内容是在文件大小增加之前写入的,因此不可能通过断电或系统崩溃将垃圾引入回滚日志。

这似乎至少提供了部分答案。

4

2 回答 2

1

关于linux,您写入缓冲区的内容不能保证立即写入磁盘。

kernel复制data到 abuffer中,然后在后台,内核收集所有的 ,对dirty buffers它们进行最佳排序并将它们写到disk. 这称为writeback. 这允许写入调用以闪电般的速度发生,几乎立即返回。它还允许内核进行defer writes更多idle periods和批量处理writes together

于 2013-01-21T17:02:43.010 回答
0

这在很大程度上取决于正在使用的文件系统 ( ext3, ext4, xfs, ....) 和为其提供的挂载时间选项,因此没有一个简单的万能答案。也许如果您向我们展示您的/etc/fstab并告诉我们您想了解哪个文件系统,可以给出更好的答案......

于 2013-01-21T17:35:25.577 回答