【发布时间】:2016-04-16 21:29:57
【问题描述】:
我需要在 java 代码中实现一个快速简单的 hdfs get 功能,它的工作方式与命令行“hadoop fs get”非常相似,因为它支持通配符。
使用Filesystem.copyToLocalFile() 方法似乎无法提供此功能,但使用适当参数运行FsShell.run() 似乎调用了确切的命令行功能,但由于某种原因,它在执行获取时会引发空指针异常。
我的代码如下:
Configuration conf = new Configuration();
conf.set("fs.hdfs.impl", org.apache.hadoop.hdfs.DistributedFileSystem.class.getName());
conf.set("fs.file.impl", org.apache.hadoop.fs.LocalFileSystem.class.getName());
FileSystem.setDefaultUri(conf, "hdfs://192.168.61.129:8020");
FsShell hdfsShell = new FsShell(conf);
String src = "/user/andrei-test/test.txt";
String dst = "D:/temp/";
hdfsShell.run(new String[]{ "-get", src, dst });
我还注意到在做 put 时:
hdfsShell.run(new String[]{ "-put", "D:/temp/test.txt", "/user/andrei-test/test-put.txt" });
一切正常。
进入调试模式,我注意到 java.lang.ProcessBuilder.start() 方法抛出了异常:
for (String arg : cmdarray)
if (arg == null)
throw new NullPointerException();
当cmd数组有以下值时:
[null, chmod, 0644, D:\temp\test.txt._COPYING_]
从这里我有点难过,以前有人遇到过这个问题吗?我也找不到在 google 上使用 FsShell.run() 进行 get 的示例,我觉得这有点奇怪。
【问题讨论】:
-
您的 cmdarray 转储有
chmod,但您在上面发布的代码在调用 hdfsShell 时有get。你确定你做对了吗? -
我很确定它是正确的,再次,带有 put 的版本,正如我同时尝试过的那样,带有 rm 的工作就好了。我假设 D:\temp\test.txt._COPYING_ 是为反映操作状态或类似内容而创建的中间文件。
-
作为一个小更新,我已经在单独的 hadoop 集群、我们在这里使用的开发集群以及我在本地运行的 hortonworks vm 上检查了这一点。我正在使用的依赖项是 hadoop-common 和 hadoop-hdfs,我也尝试过使用它们的不同版本。在所有这些情况下,我都得到了相同的结果。
-
如果您发布堆栈跟踪可能会有所帮助
-
对不起,是的,我想我可以从堆栈跟踪开始。 pastebin.com/K0796e9F