使用Java通过其inode查找文件

问题描述 投票:1回答:2

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

java linux file inode
2个回答
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%可靠的过程做好准备,上述内容可能会让您到达目的地。


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编号,则文件将在应用程序中保持打开状态,无论其新名称如何,它都可以读取/写入文件,尽管其名称已更改。
© www.soinside.com 2019 - 2024. All rights reserved.