简体   繁体   中英

Modification in symbolic link

How to identify which link modified the target file when multiple symbolic link exists for a single file using Java? I was unable to find which file modified the target file.

Example: D:\\sample.txt,D:\\folder1\\sample.txt ; these two are links. The target file is located in E:\\sample.txt .

Now how to identify whether D:\\sample.txt or D:\\folder1\\sample.txt modified the E:\\sample.txt ?

How to identify which link modified the target file when multiple symbolic link exists for a single file using java?

It is not possible.

It is not possible in any programming language.

This functionality would have to be supported by the operating system, and no operating system I've ever come across does.


There are heuristics (using timestamps) that will probably work "most of the time", but in each case there are circumstances under which the heuristic will give no answer or even the wrong answer. Here are some of the confounding issues:

With simple timestamp heuristics:

  • it won't if either of the symlinks is on a read-only file system, or a file system where access times are not recorded (eg depending on mount options), and

  • it won't work if a file read occurs on the symlink after the last file write.

When you add a watcher:

  • it won't work if you weren't "watching" at the time (duh!), and

  • it won't work if you have too many watcher events ... and you can't keep up.

(Besides, I don't think you can get events on the use of a symlink. So you would still need to check the symlink access timestamps anyway. And that means that read-only file systems, etc are a problem here too.)

And then there are scenarios like:

  • both symlinks are used to write the file,
  • you don't know about all of the symlinks, or
  • the symlink used for writing has been deleted or "touched".

These are probably beyond of the scope of the OP's use-case. But they are relevant to the general question as set out by the OP's first sentence.

Maybe you can do that using Files.readAttributes() . The below works with Linux , since when you "use" a symlink under Linux, its last access time is modified. No idea under Windows, you'll have to test.

If symlink1 is a Path to your first symlink and symlink2 a Path to your second symlink, and realFile a Path to your real file, then you can retrieve FileTime objects of the last access time for both symlinks and last modification time of the file using:

Files.readAttributes(symlink1, BasicFileAttributes.class).lastAccessTime();
Files.readAttributes(symlink2, BasicFileAttributes.class).lastAccessTime(); 
Files.readAttributes(realFile, BasicFileAttributes.class).lastModifiedTime();

Since FileTime is Comparable to itself, you may spot which symlink is modified but this is NOT a guarantee.

Explanation: if someone uses symlink1 to modify realFile , then the access time of symlink1 will be modified and the modification time of realFile will be modified. If the last access time of symlink1 is GREATER than the last access time of symlink2 , then there is a possibility that symlink1 was used for this operation; on the other hand, if the last access time of symlink2 is greater and the last modification time of realFile is lesser, then you are sure that symlink2 was not used for this purpose.

But again there is no REAL guarantee. Those are only heuristics!


You should also have a look at using a WatchService in order to watch for modifications on the real file; this would make the heuristics above more precise even. But again, no guarantee.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM