如何将Hadoop Path对象转换为Java File对象

10

是否有一种方法可以将一个有效且现有的Hadoop Path对象转换为一个有用的Java File对象?是否有一种好的方式来完成这个转换,还是需要费尽心思地编写代码?更明显的方法行不通,似乎这应该是一个常见的代码片段。

void func(Path p) {
  if (p.isAbsolute()) {
     File f = new File(p.toURI());
  }
}

由于Path::toURI()返回的是"hdfs"标识符,而Java的File(URI uri)构造函数只能识别"file"标识符,因此这种方法不起作用。

有没有一种方法可以让Path和File共同使用?

**

好的,请给出一个具体的有限例子。

Path[] paths = DistributedCache.getLocalCacheFiles(job);
DistributedCache 应该提供一个本地化的文件副本,但是它返回一个路径(Path)。我假设 DistributedCache 会在同一磁盘上制作文件的本地副本。在这个简单的例子中,我们希望 HDFS 不参与其中,那么有没有一种可靠的方法可以将 Path 转换为 File?

假设java.nio.file.Path是可接受的(而不是java.io.File),这个库似乎很有前途。 - dimo414
3个回答

13

我最近也有同样的问题,确实有一种方法可以从路径中获取文件,但这需要临时下载该文件。显然,这对许多任务来说并不合适,但如果时间和空间对你不是很重要,而你只需要使用Hadoop中的文件,可以尝试以下操作:

import java.io.File;
import java.io.IOException;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;

public final class PathToFileConverter {
    public static File makeFileFromPath(Path some_path, Configuration conf) throws IOException {
        FileSystem fs = FileSystem.get(some_path.toUri(), conf);
        File temp_data_file = File.createTempFile(some_path.getName(), "");
        temp_data_file.deleteOnExit();
        fs.copyToLocalFile(some_path, new Path(temp_data_file.getAbsolutePath()));
        return temp_data_file;
    }
}

2
如果您获得了一个LocalFileSystem对象
final LocalFileSystem localFileSystem = FileSystem.getLocal(configuration);

您可以将您的Hadoop Path对象传递给localFileSystem.pathToFile函数。
final File localFile = localFileSystem.pathToFile(<your hadoop Path>);

1
java.lang.IllegalArgumentException: 错误的文件系统:hdfs://ip-XXX-XX-X-XXX:8020/HDFS_PATH,期望的是:file:///。 - m-bhole

0

我不知道有这样的方法。

据我了解,在Hadoop中,Path表示分布式文件系统中节点的标识符。这与java.io.File是不同的抽象概念,后者代表本地文件系统上的节点。Path对象甚至不能具有等效行为的File表示,因为其底层模型根本不同。

因此,无法实现转换。我猜你认为File对象更有用,是想使用已有的库方法吗?由于上述原因,这种方法并不可行。如果这是你自己的库,那么你可以将其重写以便与Hadoop Paths清晰地配合,并将任何File对象转换为Path对象(因为Paths是Files的严格超集)。如果这是第三方库,那你就没办法了;该方法的作者没有考虑到分布式文件系统的影响,只编写了能够在普通的本地文件上运行的方法。


9
这个回答是错误的:Hadoop Path 不是 Hadoop 文件系统中节点的标识符,而是任何文件系统中的文件或目录。Hadoop FileSystem 是通用的,可以支持不同的文件系统,而不仅仅是 HDFS。文档中清楚地写明了这一点。Hadoop Path 无法转换为 Java File 的原因并不是它们代表两种不同的抽象。 - mariop

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接