为什么检查hadoop中是否存在文件会导致NullPointerException?

我正在尝试创建或打开一个文件来存储HDFS中的一些输出,但是当我在下面的代码片段的倒数第二行调用exists方法时,我得到一个NullPointerException:

 DistributedFileSystem dfs = new DistributedFileSystem(); Path path = new Path("/user/hadoop-user/bar.txt"); if (!dfs.exists(path)) dfs.createNewFile(path); FSDataOutputStream dos = dfs.create(path); 

这是堆栈跟踪:

 java.lang.NullPointerException at org.apache.hadoop.dfs.DistributedFileSystem.getFileStatus(DistributedFileSystem.java:390) at org.apache.hadoop.fs.FileSystem.exists(FileSystem.java:667) at ClickViewSessions$ClickViewSessionsMapper.map(ClickViewSessions.java:80) at ClickViewSessions$ClickViewSessionsMapper.map(ClickViewSessions.java:65) at org.apache.hadoop.mapred.MapRunner.run(MapRunner.java:47) at org.apache.hadoop.mapred.MapTask.run(MapTask.java:227) at org.apache.hadoop.mapred.TaskTracker$Child.main(TaskTracker.java:2209) 

问题是什么?

我认为这样做的首选方式是:

 Configuration conf = new Configuration(); conf.set("fs.default.name", "hdfs://mynamenodehost:9000"); FileSystem fs = FileSystem.get(conf); Path path = ... 

这样您就不会将代码绑定到FileSystem的特定实现; 另外,您不必担心如何初始化FileSystem的每个实现。

默认构造函数DistributedFileSystem()不执行初始化; 你需要显式调用dfs.initialize()。

获得空指针exception的原因是DistributedFileSystem内部使用DFSClient的实例。 由于未调用initialize(),因此DFSClient的实例为null。 getFileStatus()调用dfsClient.getFileInfo(getPathName(f) – 导致NullPointerException,因为dfsClient为null。

请参阅https://trac.declarativity.net/browser/src/hdfs/org/apache/hadoop/dfs/DistributedFileSystem.java?rev=3593

这个应得的工作

 DistributedFileSystem dfs = new DistributedFileSystem(); dfs.initialize(new URI("URI to HDFS"), new Configuration()); Path path = new Path("/user/hadoop-user/bar.txt"); if (!dfs.exists(path)) dfs.createNewFile(path); FSDataOutputStream dos = dfs.create(path);