gpt4 book ai didi

在文件打开时检查 C 中文件指针的有效性

转载 作者:太空狗 更新时间:2023-10-29 11:41:43 24 4
gpt4 key购买 nike

一般来说,一旦文件句柄打开,文件就打开了,任何人改变目录结构都无法改变这一点——文件可以被移动、重命名,或者在它的位置放置其他东西——它保持打开状态构造,因为在 Linux/Unix 中没有真正的文件删除,只有 unlink,它不一定删除文件 - 它只是从目录中删除链接。结果:无论文件发生什么情况,文件句柄都将保持有效。

但是,如果底层设备消失了(例如,文件位于从系统中移除的 U 盘上),那么将无法再访问该文件。

我有一个程序可以在启动时打开一些其他应用程序的巨大二进制文件(> 4 GB)。之后,它通过查询监视文件的变化

long int pos = fseek(filepointer, 0L, SEEK_END);

如果结果与 pos_before 不同,则经常(每隔几毫秒)并恢复到之前的位置。在这种情况下,fgets 用于从文件中读取新数据。

因此,只扫描文件尾部的变化,使整个过程相当轻量级。但是,它受到潜在问题的影响,即如果文件系统更改(见上文),始终打开的文件指针可能会变得无效。

代码不需要移植到任何非 Linux/Unix 系统。

问题:

  • 如何检测文件指针在成功打开文件后是否仍然有效(这个事件可能发生在数周前)?我已经看到有人可以使用 fcntl(fileno(filepointer), F_GETFD) 进行测试。

替代问题:

  • 以其他方式检测文件大小的变化是否可行?我可以考虑定期使用
    • fseek(filepointer, 0L, SEEK_END);(可能非常慢并导致大量 I/O),或者
    • _filelength(fileno(filepointer));(不清楚这是否会导致大量 I/O)
    • stat(文件名, &st); st.st_size;(不清楚这是否会导致任何 I/O)

最佳答案

好吧,通常一个打开的文件会阻止卸载文件系统,所以它不应该就这么消失在你的身下。尽管使用 USB 磁盘等,用户当然有可能在不询问系统的情况下拔出设备。

但是如果进程阻止完全卸载会更好。这需要两件事:

  1. 不要让文件一直打开
  2. 不要将包含目录保留为进程工作目录。

正在运行 stat(2)定期在路径上将是执行此操作的方法。您可以检测文件的更改,包括对 mtimectime 和文件大小的修改。 inode 编号或包含设备 (st_dev) 的错误和更改可能表明该文件不再可访问或不再是同一个文件。根据应用要求使用react。

(也就是说,假设您对该名称 当前指向的文件感兴趣,而不是您打开的同一个inode。)

至于 I/O,很可能周期性地 stating 某些东西会使 inode 缓存在内存中,因此问题更多的是关于内存使用而不是 I/O。 (直到你对足够多的文件执行此操作而无法缓存它们,这会导致垃圾处理,内存和 I/O 问题......)寻找文件末尾同样需要加载长度文件,我不明白为什么这会导致任何重要的 I/O。

另一种选择是使用 inotify(7)在文件或整个目录上检测更改而无需轮询。它还可以检测卸载事件。

关于在文件打开时检查 C 中文件指针的有效性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43306503/

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