rafael c
rafael c

Reputation: 21

Find file by its inode using Java

I'm working on software that deals with files, and I need to be able to find a file regardless if it has been moved, renamed, etc. Is there if there some way to do so by searching its inode thru Java?

Upvotes: 2

Views: 3879

Answers (2)

Pierce Hanley
Pierce Hanley

Reputation: 126

There are two parts to this: getting the inode for a file you already know about, and later finding the file with that inode.

There is a mechanism for doing the former, but it's not guaranteed.

import java.nio.file.Files;
import java.io.IOException;

// ...

private static OptionalLong findInode(File file)
    throws IOException /* , SecurityException */ {

  try {
    Long inode = Files.getAttribute(file.toPath(), "unix:ino");
    return inode != null ? OptionalLong.of(inode) : OptionalLong.empty();
  }
  catch (UnsupportedOperationException | IllegalArgumentException e) {
    // getting an inode is unsupported for this JVM or that filesystem
    return OptionalLong.empty();
  }
}

As for later finding the file based on that inode, that's trickier-to-impossible. The native filesystem API may or may not offer a quick way to do that in the first place, I don't know. I suspect not, which is why the general command-line solution for this uses the find command.

And that's where you get into there being some particularly fragile aspects of this approach. As Zaboj Campula mentioned, you can't guarantee that "move" or "rename" operations were performed in a way that preserved the original inode.

If they were, you could theoretically reproduce the functionality of find in Java by recursing through the FileSystem of the original path and checking each file's inode using the method above. But even doing that, you can't guarantee that you'll be able to find them recursively. For example, the file might've been moved into a directory that you don't have permission to access. You also have to be prepared that multiple paths might share the same inode. And since this question is based on the possibility that files are getting moved around in the background, there's always the possibility that that will occur during your recursive descent, and move it to a place you'd already searched.

So as long as you're prepared for this to not be a 100% reliable process, the above might get you where you're going.

Upvotes: 6

Zaboj Campula
Zaboj Campula

Reputation: 3360

Java does not know anything about inodes. Inode is a feature of the underlying filesystem and java is a portable system and it may run on filesystem without inodes.

If you need a general solution you are out of luck. There is no general way to do that. Neither solution based on inodes is perfect because inode is change when the file is moved across filesystem bondaries. Moreover a filesystem managers may implement move operation via copy and delete even if the source and destination are at the same filesystem.

If a solution based on inodes is sufficient then you have a few options

  • Call an external binary like java.lang.Runtime.getRuntime().exec(new String[]{"ls","-i"}) to get inode and then find inode file again via external tool like find /path -inum <inode-number>.

  • Write a native code that executes the dirty filesystem dependent code and calls native functions over JNI.

  • If application opens a file and the file is renamed or moved later and the inode number is not changed the file remains opened in application regardless its new name and it can read/write file although its name is already changed.

Upvotes: 1

Related Questions