HDFS实际应用场景之文件合并


①场景:合并小文件存放到HDFS上,列如,当需要分析来自许多服务其的Apache日志时,各个日志文件可能比较小,然而Hadoop更合适处理大文件,效率会更高,此时就需要合并分散文件。如果先将所有文件合并,在复制上传到HDFS上的话,需要占用用本地计算机的大量磁盘空间。采取在向HDFS复制上传文件的过程中将小文件进行合并,效果会更好。
②开发程序

开发一个PutMerge程序,用于将合并文件后放入HDFS。
③命令getmerge
用于将一组HDFS文件在复制到本地计算机一起合并。
1)hadoop fs -put dataout1 daout daout6 /tmp
//将多个文件夹上同时传到HDFS /tmp目录下
2)hadoop fs -put trade_info.txt datain /sort1
//将trade_info.txt和datain文件同时上传到/sort1下
3)hadoop fs -getmerge /sort1 /root/yunfan1
//将这几个文件合并为一个文件
代码实现
文件的上传和下载就是字节字符流的读写操作。
读文件:输入流–>read
写文件:输出流 –>write
分析:
localFileSystem(本地)中的许多小文件上传到(合并)到HDFS
①本地每个文件打开输入流进行读取内容
②HDFS文件打开输出流,进行内容写入
③循环操作
④关闭流

public class PutMerge {
/**
*
* @param LocalDir
* 本地要上传的文件目录
* @param hdfsFile
* HDFS上的文件名称,包括路径
* @throws Exception
*/

public static void put(String localDir,String hdfsFile) throws Exception{
//获取配置信息
Configuration conf = new Configuration();
//本地路径
Path localPath = new Path(localDir);
//HDFS路径
Path hdfsPath = new Path(hdfsFile);
//获取本地文件系统
FileSystem localFs = FileSystem.getLocal(conf);
//获取HDFS
FileSystem hdfs = FileSystem.get(conf);
//本地文件系统中指定目录中所有文件
FileStatus[] status = localFs.listStatus(localPath);
//打开HDFS文件的输出流
FSDataOutputStream fsDataOutputStream = hdfs.create(hdfsPath);
//循环遍历本地文件
for(FileStatus fileStatus : status){
Path path = fileStatus.getPath();
System.out.println("文件为:" + path.getName());
//打开文件输入流
FSDataInputStream fsDataInputStream = localFs.open(path);
//进行流的读写操作
byte[] buffer = new byte[1024];
int len =0;
while((len = fsDataInputStream.read(buffer)) > 0 ){
fsDataOutputStream.write(buffer, 0, len);
}
//关闭输入流
fsDataInputStream.close();
}
}

public static void main(String[] args) throws Exception {

String localDir = "F://hukairan1";
String hdfsFile = "hdfs://192.168.8.90:9000/nihao";
put(localDir,hdfsFile);

遇到的问题:类似:1.Exception in thread “main” java.lang.IllegalArgumentException: Wrong FS: hdfs://192.168.130.54:9000/user/hmail/output/part-00000, expected: file:///
2.运行一半就报错
最后解决办法:1.hadoop需要把集群上的core-site.xml和hdfs-site.xml放到当前工程下。eclipse工作目录的bin文件夹下面。因为是访问远程的HDFS 需要通过URI来获得FileSystem.
2.弄清楚输入流和输出流。本来是关闭输入流fsDataInputStream.close();,结果我写错了fsDataOutputStream.close();
3.对于问题:eclipse看不到工程里面的bin目录看不到工程里面的bin目录及bin目录里面的class文件的解决办法是window->show view->navigator:

智能推荐

注意!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。



 
© 2014-2019 ITdaan.com 粤ICP备14056181号  

赞助商广告