袋熊的树洞

日拱一卒,功不唐捐

0%

Hadoop的FileNotFound问题

在实验《Hadoop权威指南 第3版》书本上的例子4-2时发现了一个关于 FileSystem 的问题。例子代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.IOUtils;
import org.apache.hadoop.io.compress.CompressionCodec;
import org.apache.hadoop.io.compress.CompressionCodecFactory;

import java.io.InputStream;
import java.io.OutputStream;
import java.net.URI;

public class FileDecompressor {
public static void main(String[] args) throws Exception {
String uri = args[0];
Configuration conf = new Configuration();
FileSystem fs = FileSystem.get(URI.create(uri), conf);

Path inputPath = new Path(uri);
CompressionCodecFactory factory = new CompressionCodecFactory(conf);
CompressionCodec codec = factory.getCodec(inputPath);
if (codec == null) {
System.err.println("No codec found for " + uri);
System.exit(1);
}

String outputUri =
CompressionCodecFactory.removeSuffix(uri, codec.getDefaultExtension());

InputStream in = null;
OutputStream out = null;
try {
in = codec.createInputStream(fs.open(inputPath));
out = fs.create(new Path(outputUri));
IOUtils.copyBytes(in, out, conf);
} finally {
IOUtils.closeStream(in);
IOUtils.closeStream(out);
}
}
}

编译好按照使用书本上的命令行运行程序

1
% hadoop FileDecompressor file.gz

运行时抛出了 java.io.FileNotFoundException 异常

错误说找不到文件 __/user/luowanqian/file.gz__,但是我的 file.gz 并不在这个目录里面,而是在 __/home/luowanqian/Downloads/Temp/MaxTemperature__,如果使用绝对路径作为参数传递给程序也会报错,最终在绝对路径前面加上 file:// 后程序就没有报错了。

初步分析了这个问题,个人认为是程序默认在HDFS中寻找 __file.gz__,而 file.gz 是在本地文件系统中,因此程序要识别这个文件是在本地文件系统中,需要在路径前面添加 __file://__,为了进一步验证我的猜想,我修改了原来的代码。

1
FileSystem fs = FileSystem.get(URI.create(uri), conf);

修改成

1
FileSystem fs = FileSystem.getLocal(conf);

再次使用下面命令运行程序

1
% hadoop FileDecompressor file.gz

这个时候程序就正常运行了

至于程序如何判断文件是在怎么样的文件系统目前还不知道怎么解决,初学Hadoop还是很多地方不清楚。