import java.io.File;
import java.io.IOException;
import java.util.zip.GZIPOutputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
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;
import org.apache.hadoop.io.Text;
/**
* zip to gzip
* @author Administrator
*
*/
public class Zip2Gzip {
public static boolean isRecur = false;
public static void main(String[] args) throws IOException {
Configuration conf = new Configuration();
// conf.set("fs.defaultFS", "hdfs://188.188.8.201:9000");
//System.setProperty("HADOOP_USER_NAME", "hadoop");
FileSystem fs = FileSystem.get(conf);
//args[0] 类名称
Path zipDir = new Path(args[0]); //zip文件的目录
Path unZipDir = new Path(args[1]);//解压后的文件目录
Text zipFile= new Text(args[2]); //zip文件包含的字符
//解压收的文件目录如果没有就创建
if(!fs.exists(unZipDir)){
fs.mkdirs(unZipDir);
}
transform(zipDir, unZipDir, fs, zipFile);
System.exit(0);
}
/**
*
* 解压zip文件,并合并到一个文件中 最后再将文件压缩成.gz文件
* @param zipDir zip压缩文件目录
* @param unZipDir zip文件解压到该目录
* @param hdfs
* @param zipFile zip文件中包含的字符(建议使用 .zip)
*
*/
public static void transform(Path zipDir, Path unZipDir,
FileSystem fs, Text zipFile) {
try {
//获取zipDir路径下的所有文件
FileStatus[] inputFiles = fs.listStatus(zipDir);
for (int i = 0; i < inputFiles.length; i++) {
//如果是一个目录就继续遍历(递归调用)
if (!fs.isFile(inputFiles[i].getPath())) {
transform(inputFiles[i].getPath(), unZipDir, fs,zipFile);
return ;
}
//zipFile是需要解压的文件的文件名称中的字符,这里判断一下目标目录下的文件是不是包含这个字符串
if(inputFiles[i].getPath().getName().contains(zipFile.toString()) == true){
//如果包含,就打印文件的名称
System.out.println(inputFiles[i].getPath().getName());
//在hdfs上使用流的形式进行读取文件,所以这里使用hdfs开启一个输入流,用来读取目标文件
FSDataInputStream in = fs.open(inputFiles[i].getPath());
//对zip文件进行解压,使用装饰模式,调用zipInputStream输入流进行读取zip文件
ZipInputStream zipInputStream = null;
try{
zipInputStream = new ZipInputStream(in);
ZipEntry entry;
//将解压后的多个文件进行合并
//File.separator是分隔符
//使用文件系统创建文件
//文件名:
//inputFiles[i].getPath().getName().substring(0, inputFiles[i].getPath().getName().indexOf("."))
FSDataOutputStream mergerout = fs.create(new Path(unZipDir + File.separator +
inputFiles[i].getPath().getName()
.substring(0, inputFiles[i].getPath().getName().indexOf("."))));
while((entry = zipInputStream.getNextEntry()) != null){
//设置5M的缓存
int byteSize=5*1024*1024;
byte[] buf = new byte[byteSize];
int num;
while((num = zipInputStream.read(buf,0, byteSize)) != -1){
mergerout.write(buf, 0, num);
}
}
mergerout.flush();
mergerout.close();
zipInputStream.close();
}catch(IOException e){
continue;
}
in.close();
//使用GZIPOutputStream将解压后的文件压缩成gzip格式
GZIPOutputStream gzipOutputStream = null;
try{
FSDataOutputStream out = null;
//通过文件系统创建输出流,将解压后的文件输出为.gz格式
out = fs.create(new Path(unZipDir + File.separator +
inputFiles[i].getPath().getName()
.substring(0, inputFiles[i].getPath().getName().indexOf(".")) + ".gz"));
FSDataInputStream inputStream = null;
//同样使用装饰模式来完成压缩工作
gzipOutputStream = new GZIPOutputStream(out);
//通过文件系统开启输出流,读取解压后的文件
inputStream = fs.open(new Path(unZipDir + File.separator + inputFiles[i].getPath().getName()
.substring(0, inputFiles[i].getPath().getName().indexOf("."))));
//缓冲输出 5M
int byteSize=5*1024*1024;
byte[] buffer = new byte[byteSize];
int len;
while((len = inputStream.read(buffer)) > 0){
gzipOutputStream.write(buffer, 0, len);
}
inputStream.close();
gzipOutputStream.finish();
gzipOutputStream.flush();
out.close();
}catch (Exception exception){
exception.printStackTrace();
}
gzipOutputStream.close();
//将zip解压得到文件(中间文件)删除
String tempfiles = unZipDir + File.separator + inputFiles[i].getPath().getName()
.substring(0, inputFiles[i].getPath().getName().indexOf("."));
try{
//判断文件是不是存在,如果存在就删除
if(fs.exists(new Path(tempfiles))){
fs.delete(new Path(tempfiles), true);
}
}catch(IOException ie){
ie.printStackTrace();
}
}
}
}catch (IOException e) {
e.printStackTrace();
}
}
}
HDFS编程之 .zip 转 .gz
最新推荐文章于 2023-10-08 13:01:14 发布