今天梦翔儿,成功实现hadoop编程,将本地文件夹中多个文件,合并为一个文件并上传到hdfs中
直接上代码:PutMerge.java
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 {
public static void main(String[] args) throws IOException {
Configuration conf = new Configuration();
FileSystem hdfs = FileSystem.get(conf); //获得hdfs文件系统设置
//FileSystem hdfs = DistributedFileSystem.get(conf);
FileSystem local = FileSystem.getLocal(conf); //获得本地文件系统设置
Path inputDir = new Path(args[0]); //本地输入目录
Path hdfsFile = new Path(args[1]); //远程输出文件
try {
FileStatus[] inputFiles = local.listStatus(inputDir); //数组,用来循环保存本地文件目录信息
FSDataOutputStream out = hdfs.create(hdfsFile); //创新输出hdfs文件
for (int i = 0; i < inputFiles.length; i++) { //循环取出本地文件目录信息
System.out.println(inputFiles[i].getPath().getName()); //主要关心文件名
FSDataInputStream in = local.open(inputFiles[i].getPath()); //打开本地文件
byte buffer[] = new byte[256];
int bytesRead = 0;
while ((bytesRead = in.read(buffer)) > 0) {
out.write(buffer,0, bytesRead); //合并文件
}
in.close();
}
out.close();
} catch (IOException e) {
// TODO: handle exception
e.printStackTrace();
}
}
}
=========
手动编译并执行过程:
cd /usr/lib/hadoop
sudo mkdir putmerge
sudo mkdir putmerge/src
sudo mkdir putmerge/classes
sudo cp ~/workspace/PutMerge/src/PutMerge.java putmerge/src //源码拷进
cd putmerge/
ls
cd src
ls
cd ../..
sudo javac -classpath hadoop-0.20.2-cdh3u0-core.jar:lib/commons-cli-1.2.jar -d putmerge/classes putmerge/src/PutMerge.java //编译
sudo jar -cvf putmerge/PutMerge.jar -C putmerge/classes/ .
sudo mkdir input2
sudo nano input2/test1.txt //两个输入文件
111-111
111-222
111-333
sudo nano input2/test2.txt
222-111
222-222
222-333
hadoop jar putmerge/PutMerge.jar PutMerge input2 hdfs://localhost/usr/cloud/output2 //执行程序
梦翔儿最终通过50070的hdfs web查看输出:
hdfs://localhost/usr/cloud/output2
222-111
222-222
222-333
111-111
111-222
111-333
=========
注:在ubuntu的eclipse中两个参数如果都是本地,成功。但第二个参数设为hdfs时执行出错,提示:Wrong FS: hdfs://localhost/user/cloud,expected: file:///,不知何故。
但如上进行手动编译,执行是成功的。看起来无论是本地还是远程,执行的过程都是相同的。也就是说hdfs 的接口也是一种标准的java类,在本地也是可以执行的。
在梦翔儿的实验中,是按本地的一大堆出租车轨迹日志,合并成一个大文件,送到hdfs(因为hdfs对大文件的处理效率比较好,一堆小文件效率差)上后用mapreduce来分析查询。
原始程序参考于 《hadoop in action 》 P36-37 关于其它的算法,以后再具体实践。