gpt4 book ai didi

c - fflush 和 'no disk space left'

转载 作者:太空宇宙 更新时间:2023-11-04 06:09:42 25 4
gpt4 key购买 nike

我正在编写一个程序,某种数据库。当我阅读 fclose(3) 手册时,我发现它调用 fflush(3)FILE* 缓冲区刷新到磁盘(实际上是操作系统缓冲区,但现在没关系,我们可以随时调用 fsync(2))。

因为我正在编写数据库,所以很明显我想防止数据丢失。如果没有磁盘空间并且 fclose(3) 中的 fflush(3) 失败 — 我们将丢失数据,因为

using FILE* after an error in fclose() will cause undefined behavior

所以我考虑在 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;
}

最佳答案

后续 fflush() 操作成功的原因是没有(新)数据要写入磁盘。第一次 fflush() 失败;那是悲惨的历史。随后的 fflush() 没有做任何事情,所以它成功了。

如果您正在写入数据库,则必须小心每次写入 - 而不仅仅是在最后处理问题。根据您的数据的重要性,您可能需要经历各种反复来处理问题 - DBMS 很复杂是有原因的,写入失败就是其中之一。

处理该问题的一种方法是为数据预先分配空间。正如其他人所指出的,经典的 Unix 文件系统允许稀疏文件(文件中有空 block ,没有为其分配磁盘空间),因此您实际上必须在需要分配的每个页面上写入一些数据。然后,当您扩展空间时,您只需担心“磁盘已满”问题 - 并且您知道什么时候这样做,并且您可以小心地处理该故障。

在基于 Unix 的系统上,有多种系统调用可以帮助您同步磁盘上的数据,以及“打开”选项等。其中包括“O_DSYNC”和相关值。然而,如果你正在扩展一个文件,它们仍然会因为“空间不足”而导致失败,即使有花哨的同步选项。当您确实遇到该故障时,您必须等待空间可用(因为您可能要求用户告诉您它何时可用),然后再次尝试写入。

关于c - fflush 和 'no disk space left',我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2215363/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com