在Unix中没有“copy”这样的东西。即使是用于复制文件(sendfile和copy_file_range)的最先进的系统调用,也最终归结为使用中间缓冲区在两个独立文件之间复制数据。
但是你可以使用一些猜测来确定文件副本具有相当程度的确定性。
假设,即
- 两个文件是开放的:A和B(没有特定的顺序)
- A由(IN_ACCESS)
- B被写入(IN_MODIFY)
- 一读和B已关闭
- A已开放供阅读(由IN_CLOSE_NOWRITE标识)
- B已开放供书写(由IN_CLOSE_WRITE标识)
- A和和B具有相同的数据大小(stat.st_size)之后
。注意,上面的序列只是共同启发式,不严格的规则。可能还有其他事件的顺序不明显(例如在打开源文件之前截断或移位目标文件IN_MODIFY)。复制过程可能会取消链接现有目标文件并创建专门用于复制的新文件,在这种情况下,新文件必须是及时受inotify(!!)的观察。由于订阅竞赛,您可能会错过一些(或全部)事件,这些设计完全无法检测到。
由于inotify队列溢出(IN_Q_OVERFLOW),您可能会大量丢失事件。
Inotify无法检测mmap-ed文件中的内存中操作,而mmap通常用于文件复制。因此整个步骤2和3可能会丢失。
您还没有指定目标文件系统(以及您是否期望在非受控环境中使用inotify),但要注意,有些文件系统可能不支持inotify(基于FUSE和网络文件系统往往是特别有问题的)。在FUSE的情况下,这可能取决于特定的文件系统和内核版本。
创建硬链接并不严格限定为副本,但它可能会导致类似于该情况的验尸模式(两个文件具有相同大小和相同表观内容),所以应用程序应该更好地识别inode。
由于上述原因,使用inotify标识副本太繁琐,除非您期望获得显着的回报。你应该考虑从识别副本开始,使用静态分析(因为无论如何你有时会回退到它)。
感谢您的回答。这非常有帮助。 –