【发布时间】:2011-01-13 23:52:39
【问题描述】:
我正在编写一个程序,某种数据库。当我阅读fclose(3) 的手册时,我发现它调用fflush(3) 将FILE* 缓冲区刷新到磁盘(实际上是操作系统缓冲区,但现在没关系,我们总是可以调用fsync(2))。
因为我正在编写数据库,所以很明显我想防止数据丢失。如果没有磁盘空间并且fclose(3) 中的fflush(3) 失败——我们将丢失我们的数据,因为
在
fclose()出现错误后使用FILE*将导致未定义的行为
所以我考虑在fclose(3) 之前明确使用fflush(3),警告用户磁盘空间不足并在一段时间后调用fflush(3)。
我已阅读 C 标准并认为这是一个好主意。实际上,在 fflush 失败后,第二次调用总是返回 0(没有错误),但实际上什么也不做。 fsync 没有帮助我(我认为数据可能保存在 RAM 中)。
在这种情况下如何防止数据丢失?也许有一些经验法则。
这是我的测试代码:
#include <stdio.h>
int main()
{
FILE *a = fopen("/tmp/1", "wb")
if ( !a )
perror("fopen");
if ( fwrite("test", 1, 4, a) != 4 )
perror("fwrite"); // always OK, cause data is buffered
while( fflush(a) ) // ...second call will always return 0!
{
perror("fflush"); // if there is no disk space, I will get this perror, but ...
}
if ( fclose(a) ) // always ok, because calls only close(2)
perror("fclose");
return 0;
}
【问题讨论】:
-
你也可以看看其他开源程序,看看他们是如何解决这个问题的,例如 SQLite。