当使用 Java 的单个文件存在多个符号链接时,如何识别哪个链接修改了目标文件?我找不到哪个文件修改了目标文件。
示例:D:sample.txt,D:folder1sample.txt
;这两个是链接。目标文件位于 E:sample.txt
中。
现在如何识别D:sample.txt
或D:folder1sample.txt
是否修改了E:sample.txt
?
当使用 java 的单个文件存在多个符号链接时,如何识别哪个链接修改了目标文件?
这是不可能的。
这在任何编程语言中都是不可能的。
此功能必须由操作系统支持,而我遇到的操作系统都没有。
有些启发式方法(使用时间戳)可能会在"大部分时间"起作用,但在每种情况下,启发式方法都不会给出答案,甚至是错误的答案。 以下是一些令人困惑的问题:
使用简单的时间戳启发式方法:
-
如果符号链接位于只读文件系统或未记录访问时间的文件系统上(例如,取决于挂载选项),则不会,并且
-
如果在最后一次文件写入后在符号链接上发生文件读取,则它不起作用。
添加观察程序时:
-
如果你当时没有"看"(呃!),它将无法工作,并且
-
如果您有太多观察者事件,它将不起作用......而且你跟不上。
(此外,我认为您无法获得有关使用符号链接的事件。 因此,您仍然需要检查符号链接访问时间戳。 这意味着只读文件系统等在这里也是一个问题。
然后是这样的场景:
- 两个符号链接都用于写入文件,
- 您不知道所有符号链接,或者
- 用于写入的符号链接已被删除或"触摸"。
这些可能超出了OP用例的范围。 但它们与OP第一句所提出的一般问题有关。
也许您可以使用 Files.readAttributes()
.以下内容适用于 Linux,因为当您在 Linux 下"使用"符号链接时,其上次访问时间会被修改。不知道在Windows下,你必须测试。
如果symlink1
是第一个符号链接的Path
,symlink2
第二个符号链接的Path
,并且realFile
对实际文件的Path
,则可以使用以下方法检索符号链接的上次访问时间和文件上次修改时间FileTime
对象:
Files.readAttributes(symlink1, BasicFileAttributes.class).lastAccessTime();
Files.readAttributes(symlink2, BasicFileAttributes.class).lastAccessTime();
Files.readAttributes(realFile, BasicFileAttributes.class).lastModifiedTime();
由于FileTime
本身Comparable
,您可能会发现哪个符号链接被修改,但这不是保证。
说明:如果有人使用symlink1
修改realFile
,那么symlink1
的访问时间将被修改,realFile
的修改时间将被修改。如果 symlink1
的上次访问时间大于 symlink2
的上次访问时间,则有可能symlink1
用于此操作;另一方面,如果symlink2
的上次访问时间较大,而realFile
的上次修改时间较小,则确定symlink2
未用于此目的。
但同样没有真正的保证。这些只是启发式!
您还应该查看使用WatchService
以监视对真实文件的修改;这将使上面的启发式方法更加精确。但同样,没有保证。