照着《Hadoop實戰》寫了一個程序:
package my;
import java.io.IOException;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FSDataInputStream;
import org.apache.hadoop.fs.FSDataOutputStream;
import org.apache.hadoop.fs.FileStatus;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
public class PutMerge {
/**
* @param args
* @throws IOException
*/
public static void main(String[] args) throws IOException {
Path inputDir = new Path("C:\\hjfiles\\tmpdir");
Path hdfsFile = new Path("hdfs://localhost:9000/output/merge");
Configuration conf = new Configuration();
FileSystem hdfs = FileSystem.get(conf);<span style="white-space:pre"> </span>//問題出在這。
FileSystem local = FileSystem.getLocal(conf);
FileStatus[] inputFiles = local.listStatus(inputDir);
FSDataOutputStream out = hdfs.create(hdfsFile);
for (FileStatus fileStatus : inputFiles) {
FSDataInputStream in = local.open(fileStatus.getPath());
byte[] buffer = new byte[256];
int byteRead = 0;
while((byteRead = in.read(buffer))>0){
out.write(buffer, 0, byteRead);
}
in.close();
}
}
}
在本地僞分佈式環境下開發運行這個程序時,報錯:
Exception in thread "main" java.lang.IllegalArgumentException: Wrong FS: hdfs://localhost:9000/output, expected: file:///
at org.apache.hadoop.fs.FileSystem.checkPath(FileSystem.java:310)
at org.apache.hadoop.fs.RawLocalFileSystem.pathToFile(RawLocalFileSystem.java:47)
at org.apache.hadoop.fs.RawLocalFileSystem.mkdirs(RawLocalFileSystem.java:301)
at org.apache.hadoop.fs.ChecksumFileSystem.mkdirs(ChecksumFileSystem.java:470)
at org.apache.hadoop.fs.ChecksumFileSystem.create(ChecksumFileSystem.java:365)
at org.apache.hadoop.fs.FileSystem.create(FileSystem.java:484)
at org.apache.hadoop.fs.FileSystem.create(FileSystem.java:465)
at org.apache.hadoop.fs.FileSystem.create(FileSystem.java:372)
at org.apache.hadoop.fs.FileSystem.create(FileSystem.java:364)
at my.PutMerge.main(PutMerge.java:29)
原因:
在定義一個FileSystem變量的時候僞分佈式和單機版的方法是不一樣的,單機版使用的是FileSystem類的靜態函數
<span style="font-size:12px;">FileSystem hdfs = FileSystem.get(conf) </span>
僞分佈式下需要使用Path來獲得
<span style="font-size:12px;">Path dstDir = new Path("hdfs://localhost:9000/home/hadoop/hadoop");
FileSystem hdfs = dstDir.getFileSystem(getConf()); </span>
法一:
//FileSystem hdfs = FileSystem.get(conf);
FileSystem hdfs = hdfsFile.getFileSystem(conf);
//FileSystem local = FileSystem.getLocal(conf);
FileSystem local = inputDir.getFileSystem(conf);
法二:
將hadoop目錄中的conf文件夾中的hdfs-site.xml與core-site.xml複製到你的項目的目錄之下 (試過,沒生效,可能是路徑什麼的問題)