考虑这个例子:
FILE* stream = fopen("my_file", "w");
fputs("hello", stream);
如果在执行fputs()期间断电,会发生什么?
之后,我能不能找到非零大小的“my_file”,但第一个字节不是'h'? 如果是,是否保证为零,或者它是否包含任意值?
当然,假设没有其他人在触摸我们的档案。
编辑:假设目标磁盘驱动器/设备的类型能够保持足够长的时间来写入它在内部缓冲的所有数据。
POSIX有什么可说的吗? Linux吗?是Windows吗?
编辑:我不打算专注于如何实现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方法可能表示 文件系统实现“安全附加”语义。这个 表示在文件大小之前写入内容 增加,以便垃圾不可能被引入 通过断电或系统崩溃进入回滚期刊。
这似乎提供了至少部分答案。
答案 0 :(得分:1)
关于linux
,您写入缓冲区的内容不能保证写入磁盘immediatley。
kernel
将data
复制到buffer
中,稍后在后台,内核会收集所有dirty buffers
,对其进行最佳排序并将其写入disk
。这称为writeback
。这允许写入调用快速发生,几乎立即返回。它还允许内核defer writes
更多idle periods
并批量许多writes together
。
答案 1 :(得分:0)
这在很大程度上取决于正在使用的文件系统(ext3
,ext4
,xfs
,....)以及给定的挂载时间选项,因此没有一个简单的一刀切的答案。也许如果你向我们展示你的/etc/fstab
并告诉我们你想知道哪个文件系统,可以给出更好的答案......