工作的需求是,在HDFS上有每天不断产生的的日志文件文件夹,每一个文件夹下都有两个文件,一个是.log文件,还有一个是.out文件。现在要求根据日志产生的时间,按照天计算,将同一天产生的文件夹打包压缩成一个文件归档在 HDFS某个特定的目录下。操作HDFS上的文件当然就不能java自带的那一套操作文件的方式去处理了。事实上,Hadoop提供了一套api为java来操作hdfs,下面我们来看看具体是怎么实现的。
第一步,获取HDFS的FileSystem对象,对所有在HDFS中的文件的操作,都要使用这个对象提供的方法去操作,需要添加当前项目下的hadoop的两个配置文件。
1 public static FileSystem getFileSystem() throws IOException {
2 Configuration conf = new Configuration();
3 conf.addResource(new Path("conf/core-site.xml"));
4 conf.addResource(new Path("conf/hdfs-site.xml"));
5 conf.set("fs.file.impl", "org.apache.hadoop.fs.RawLocalFileSystem");
6 return FileSystem.get(conf);
7 }
第二步,获取HDFS某文件夹下所有的文件信息:
1 FileStatus[] stats = fs.listStatus(path);
2 for (FileStatus stat : stats) {
3 long time = stat.getModificationTime(); //文件的最后编辑时间
4 String filePath = stat.getPath().toString(); //文件的全路径
5 String fileName = stat.getPath().getName(); //文件名
6 boolean isFile = stat.isFile(); //路径是否是文件
7 boolean isDir = stat.isDirectory(); //路径是否是目录
8 }
第三步,得到某一个文件的输入流 ,使用hdfs提供的流:
1 FSDataInputStream HDFSIn = fs.open(new Path(fileStatus[j].getPath().toString())); //getPath():文件的完整路径
2 BufferedInputStream bis = new BufferedInputStream(HDFSIn);
第四步,在文件经过相应的处理之后,向HDFS写文件:
1 byte[] buf = new byte[1024];
2 FSDataOutputStream fsDataOutputStream = getFileSystem().create(new Path(“HDFDPath”));
3 fsDataOutputStream.write(buf);
第五步,删除没用的文件(谨慎操作!):
1 FileSystem fs = getFileSystem();
2 fs.delete(new Path(file), true); //true表示非空目录和文件会被删除,通过java删除的文件将会被永久删除,不会被放入HDFS的回收站
作此总结,希望自己再接再厉。
附上HDFS常用命令:
命令 | 作用 |
| 列出hdfs文件系统根目录下的目录和文件 |
| 向HDFS添加本地文件 |
| 拷贝文件至本地 |
| 删除文件或者目录 |
| 创建目录 |
| 给文件重命名并且保存,源文件还在 |
| 给文件重命名并且保存,源文件不在 |
| 统计目录下文件个数,目录个数,文件总大小 |
| 显示文件末尾1KB的数据 |
| 均衡内部dataNode中的文件 |