在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標識副本太繁瑣,除非您期望獲得顯着的回報。你應該考慮從識別副本開始,使用靜態分析(因爲無論如何你有時會回退到它)。
感謝您的回答。這非常有幫助。 –