HDFS编程之 .zip 转 .gz

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();
        }
    }


}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值