【发布时间】:2017-08-28 10:24:09
【问题描述】:
当我们使用系统调用 open() 然后执行 I/O 操作(尤其是 read() 和 lseek())时,如果我们在程序仍在运行时更改文件,内核缓冲区是否会更新?如果没有,那么如何将实时更新文件强制同步到内核缓冲区。
这是一个例子:
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int main()
{
int fd=0;
char ch='\0';
fd=open("test.dat",O_RDONLY);
while(1)
{
while(read(fd,&ch,1)!=0)
{
printf("%c",ch);
}
printf("\n");
lseek(fd,0,SEEK_SET);
sleep(5);
}
close(fd);
return 0;
}
现在,我在“test.dat”中有一些数据(比如:'3 3 34')。我打开了这个文件并阅读它以结束,然后再次寻找它开始。同时,在一些编辑器中,我打开了这个“test.dat”文件并更新了它的内容并保存了它们。由于 read() 和 lseek() 是系统调用,如果内核/操作系统缓冲区定期与硬盘中的文件同步,它们应对应于更新文件的更改。但事实并非如此。文件中的更改不会从 read() 中反映出来,而是继续打印初始内容。对于写作,如果有sync()、fsync()等解决方案。但是对于阅读,我们有一些这样的功能吗?
(注意:这个问题的一个简单的解决方案是 close() 和 open() 文件描述符,它完美地工作,但我想知道和理解一些不关闭文件描述符的替代方法)
【问题讨论】:
-
您需要这两个应用程序才能在共享启用模式下打开文件。您可以在程序中执行此操作,请参阅
open的选项。您可能无法强制第 3 方应用更改其打开模式。 -
至于你的问题,有程序不断地从文件中读取。带有
-f选项的tail就是这样一种程序。也许您可以查看该程序的源代码以了解它是如何工作的? -
您的编辑器可能正在将您的原始文件移动到备份中,并创建一个新文件(编辑所在的位置)。您可以使用 stat 命令轻松地再次检查,并查看在编辑文件后 inode 是否在您身上发生变化。如果您不想追求所有这些,只需使用 echo 命令附加到您的文件中,看看是否有效。