确定是否已在C中修改了打开的文件

时间:2011-12-25 04:24:01

标签: c file fopen

有没有办法确定在POSIX下是否修改了 open 文件?更具体地说,我如何在下面实施is_modified()

FILE *f = fopen("myfile", "r+");

// do various things with f

if (is_modified(f))
    foo(f);

为了提供一些上下文,我在C中编写一个模块,每个文件都需要将其哈希存储在表中。该接口为fopen()fclose()提供了包装器,并且可以在文件关闭时完成散列。我找到了几种方法来做到这一点,但都没有像我希望的那样高效,干净或防错:

  • 计算每个打开的文件的哈希值。
  • fflush(f)并检查时间戳是否已更改。
  • 围绕fwrite()fprintf()等提供包装。

有什么建议吗?

3 个答案:

答案 0 :(得分:6)

http://rosettacode.org/wiki/File_modification_time#POSIX_utime.28.29

您可以使用stat()函数检查上次修改的最新修改。

答案 1 :(得分:3)

由于您使用fopen()fclose()的封面丢弃了句柄,因此您可以在打开文件时记录fstat()的结果,并在您即将关闭时再次记录结果该文件,并比较两者。如果有任何改变,那么你有一个积极的变化,你需要重新计算哈希。如果没有任何变化,您可以确信您拥有与以前相同的文件。如果您需要消除这种不确定性,那么无论如何您都需要重新计算哈希值,因为您知道在计算哈希值时该文件可能被另一个线程或另一个进程更改。

请注意,现代POSIX(POSIX 2008)为struct stat提供时间成员:

  • struct timespec st_atim - 上次数据访问时间戳。
  • struct timespec st_mtim - 上次数据修改时间戳。
  • struct timespec st_ctim - 上次文件状态更改时间戳。

这些提供了修改时间的纳秒分辨率。出于向后兼容性的原因,可能存在以下宏:

#define st_atime st_atim.tv_sec
#define st_mtime st_mtim.tv_sec
#define st_ctime st_ctim.tv_sec

虽然AFAICS,POSIX标准并没有强制要求。但是,从(Unix)时间开始使用st_Xtime名称 - 从1978年开始使用版本7 Unix,可能在之前 - 因此系统将要保留较旧的代码编译,并且诸如那些的宏提供适度的无痛的方式。

答案 2 :(得分:3)

你也可以使用kqueue通知系统在有人更改文件时接收通知,然后使哈希条目无效/重新加载

man 2 kqueue

http://blog.julipedia.org/2004/10/example-of-kqueue.html