我有以下代码:
FILE *file = fopen("testfile.txt", "r+");
int fdfile = open("testfile.txt", O_RDONLY | O_SYNC);
const char word[] = "writing to a file and read test";
fwrite(word, sizeof(word)-1, 1, file);
fsync(fdfile);
char word1[1024] = {0};
int n = read(fdfile, word1, sizeof(word)-1);
printf("%s\n%d", word1, n);
fclose(file);
就在运行之前,该文件中testfile.txt
包含内容prev content
一旦我运行这个,我就会得到
prev content
12
尽管应该是最新的内容,writing to a file and read test
。我用过fsync(fdfile)
,没用。我也尝试过,sync()
但fsync(fileno(file))
没有一个起作用,即使它们应该起作用,因为它们应该在写入后将内容刷新到磁盘
我知道可以通过使用相同的文件描述符来读取和写入来缓解这种情况,但我无法在我的代码中这样做。如何缓解此问题并同步内容?
答案1
open()
、read()
、等函数write()
是Posix 定义的低级函数。它们通常涉及系统级别(内核)的缓冲区,这是您用来刷新到实际介质的缓冲区,fsync()
并且您对该缓冲区没有太多控制权。
fopen()
、fread()
、等函数fwrite()
是 C 语言提供的高级函数。它们涉及和额外的您可以使用 来配置缓冲区setbuf()
。此缓冲区通常是\n
文本文件(因此包括stdin
、stdout
和)的行缓冲区(在行的每一端刷新) stderr
,以及二进制文件的块缓冲区(当缓冲区已满时刷新)。
当然,不鼓励混合调用低级和高级读/写函数。您的问题是由于以下事实造成的: 所使用的高级缓冲区fwrite()
未刷新(刷新到低级缓冲区,您用 刷新fsync()
)。
解决方案是不要调用fsync()
或打开O_SYNC
(您可以从代码中删除它们);它是:
fflush()
当您需要时显式刷新高级缓冲区- 或者使高级函数无缓冲
setbuf(fdfile, _IONBF)
后者更容易,但缓冲区是为了提高效率,并且对高级调用进行取消缓冲将导致每个fwrite()
调用触发相应的write()
系统调用,这可能会对性能产生影响,这就是为什么您fflush()
在认为有必要时可能更喜欢这样做。
答案2
我想通了这个问题。
有FILE*
自己的缓冲区,需要在发生fflush()
之前进行编辑sync