使用Java通过其inode查找文件

时间:2017-09-28 17:10:38

标签: java linux file inode

我正在研究处理文件的软件,我需要能够找到一个文件,无论它是否被移动,重命名等等。是否有某种方法可以通过Java搜索其inode来实现?

2 个答案:

答案 0 :(得分:4)

这有两个部分:获取你已经知道的文件的inode,然后找到带有该inode的文件。

有一种做前者的机制,但不能保证。

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();
  }
}

至于稍后根据该inode查找文件,这是棘手的 - 不可能的。我不知道,原生文件系统API可能会或可能不会提供一种快速的方法来做到这一点。我怀疑没有,这就是为什么一般的命令行解决方案使用find命令。

这就是你在这里进入这种方法的一些特别脆弱的方面。正如Zaboj Campula所提到的,你不能保证以保留原始inode的方式执行“移动”或“重命名”操作。

如果是这样的话,理论上可以通过递归原始路径的find并使用上述方法检查每个文件的inode来重现Java中FileSystem的功能。但即使这样做,你也无法保证你能够递归地找到它们。例如,该文件可能已被移动到您无权访问的目录中。您还必须准备好多个路径可能共享相同的 inode。而且由于这个问题是基于文件在后台移动的可能性,因此总是有可能在递归下降过程中发生,并将其移动到您已经搜索过的地方

因此,只要你为此做好准备就不是100%可靠的过程,上面的内容可能会让你到达目的地。

答案 1 :(得分:0)

Java对inode一无所知。 Inode是底层文件系统的一个特性,java是一个可移植的系统,它可以在没有inode的文件系统上运行。

如果你需要一般解决方案,那你就不走运了。没有通用的方法可以做到这一点。基于inode的解决方案都不是完美的,因为当文件在文件系统绑定中移动时,inode会发生变化。此外,即使源和目标位于同一文件系统,文件系统管理器也可以通过复制和删除实现移动操作。

如果基于inode的解决方案足够,那么您有几个选项

  • 调用java.lang.Runtime.getRuntime().exec(new String[]{"ls","-i"})之类的外部二进制文件以获取inode,然后通过find /path -inum <inode-number>等外部工具再次查找inode文件。

  • 编写执行脏文件系统相关代码的本机代码,并通过JNI调用本机函数。

  • 如果应用程序打开文件并且稍后重命名或移动文件并且未更改inode编号,则无论文件名是否为新名称,文件仍将在应用程序中打开,并且文件虽然名称已更改,但仍可读/写文件。