解压缩工具类

package com.manage.util;

import java.io.*;

import java.nio.charset.Charset;
import java.util.Enumeration;
import java.util.zip.*;

import javacommon.util.FileUtil;
import org.apache.commons.compress.archivers.tar.TarArchiveEntry;
import org.apache.commons.compress.archivers.tar.TarArchiveInputStream;

import org.apache.commons.compress.archivers.tar.TarArchiveOutputStream;
import org.apache.commons.io.IOUtils;
import org.apache.tools.tar.TarEntry;
import org.apache.tools.tar.TarInputStream;
import org.apache.tools.tar.TarOutputStream;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 *  实现ZIP,tar,tar.gz等文件的解压和压缩
 */
public class ZipUtil {

    private static final int BUFFER_SIZE = 2 * 1024;
    /**
     * 是否保留原来的目录结构
     * true:  保留目录结构;
     * false: 所有文件跑到压缩包根目录下(注意:不保留目录结构可能会出现同名文件,会压缩失败)
     */
    private static final boolean KeepDirStructure = true;

    /**
     * 解压gz文件
     * @param sourcedir
     */
    public static String unGzipFile(File sourcedir,String outputDir, boolean isDelSrcFile) {
        String ouputfile = "";
        try {
            //建立gzip压缩文件输入流
            FileInputStream fi = new FileInputStream(sourcedir);
            //建立gzip解压工作流
            GZIPInputStream gzin = new GZIPInputStream(fin);
            //建立解压文件输出流
            createDirectory(outputDir,null);//创建输出目录
//            ouputfile = sourcedir.substring(0,sourcedir.lastIndexOf('.'));
//            ouputfile = ouputfile.substring(0,ouputfile.lastIndexOf('.'));
            FileOutputStream fout = new FileOutputStream(outputDir);

            int num;
            byte[] buf=new byte[1024];

            while ((num = gzin.read(buf,0,buf.length)) != -1)
            {
                fout.write(buf,0,num);
            }

            gzin.close();
            fout.close();
            fin.close();
            if(isDelSrcFile){
                sourcedir.delete();
            }
        } catch (Exception ex){
            System.err.println(ex.toString());
        }

        return outputDir;
    }
    
    /**
     * 解压缩zipFile
     * @param file 要解压的zip文件对象
     * @param outputDir 要解压到某个指定的目录下
     * @param isDelSource 是否需要删除压缩包
     * @throws IOException
     */
    public static String unZip(File file,String outputDir, boolean isDelSource) throws IOException {
        ZipFile zipFile = null;
        try {
            Charset GBK = Charset.forName("GBK");  //specifying alternative (non UTF-8) charset
            //ZipFile zipFile = new ZipFile(zipArchive, CP866);
            zipFile =  new ZipFile(file, GBK);
            createDirectory(outputDir,null);//创建输出目录
            Enumeration enums = zipFile.entries();
            while(enums.hasMoreElements()){
                ZipEntry entry = (ZipEntry) enums.nextElement();
                System.out.println("解压." +  entry.getName());
                if(entry.isDirectory()){//是目录
                    createDirectory(outputDir,entry.getName());//创建空目录
                }else{//是文件
                    File tmpFile = new File(outputDir + "/" + entry.getName());
                    createDirectory(tmpFile.getParent() + "/",null);//创建输出目录
                    InputStream in = null;
                    OutputStream out = null;
                    try{
                        in = zipFile.getInputStream(entry);;
                        out = new FileOutputStream(tmpFile);
                        int length = 0;
                        byte[] b = new byte[2048];
                        while((length = in.read(b)) != -1){
                            out.write(b, 0, length);
                        }
                    }catch(IOException ex){
                        throw ex;
                    }finally{
                        if(in!=null)
                            in.close();
                        if(out!=null)
                            out.close();
                    }
                }
            }

        } catch (IOException e) {
            throw new IOException("解压缩文件出现异常",e);
        } finally{
            try{
                if(zipFile != null){
                    zipFile.close();
                }
            }catch(IOException ex){
                throw new IOException("关闭zipFile出现异常",ex);
            }
        }
        if(isDelSource){
            file.delete();
        }
        return outputDir;
    }

    /**
     * 构建目录
     * @param outputDir
     * @param subDir
     */
    public static void createDirectory(String outputDir,String subDir){
        File file = new File(outputDir);
        if(!(subDir == null || subDir.trim().equals(""))){//子目录不为空
            file = new File(outputDir + "/" + subDir);
        }
        if(!file.exists()){
            if(!file.getParentFile().exists())
                file.getParentFile().mkdirs();
            file.mkdirs();
        }
    }

    /**
     * 解压tar.gz 文件
     * @param file 要解压的tar.gz文件对象
     * @param outputDir 要解压到某个指定的目录下
     * @param isDelSource 是否需要删除压缩包
     * @throws IOException
     */
    public static String unTarGz(File file,String outputDir,boolean isDelSource) throws IOException{
        TarInputStream tarIn = null;
        try{
            tarIn = new TarInputStream(new GZIPInputStream(
                    new BufferedInputStream(new FileInputStream(file))),
                    1024 * 2);

            createDirectory(outputDir,null);//创建输出目录

            TarEntry entry = null;
            while( (entry = tarIn.getNextEntry()) != null ){
                if(entry.isDirectory()){//是目录
                    entry.getName();
                    createDirectory(outputDir,entry.getName());//创建空目录
                }else{//是文件
                    File tmpFile = new File(outputDir + "/" + entry.getName());
                    createDirectory(tmpFile.getParent() + "/",null);//创建输出目录
                    OutputStream out = null;
                    try{
                        out = new FileOutputStream(tmpFile);
                        int length = 0;
                        byte[] b = new byte[2048];
                        while((length = tarIn.read(b)) != -1){
                            out.write(b, 0, length);
                        }
                    }catch(IOException ex){
                        throw ex;
                    }finally{
                        if(out!=null)
                            out.close();
                    }
                }
            }

        }catch(IOException ex){
            throw new IOException("解压归档文件出现异常",ex);
        } finally{
            try{
                if(tarIn != null){
                    tarIn.close();
                }
            }catch(IOException ex){
                throw new IOException("关闭tarFile出现异常",ex);
            }
        }
        if(isDelSource){
            file.delete();
        }
        return outputDir;
    }

    /**
     * .TAR文件解压
     * @param isDelSource 是否需要删除压缩包
     * @param file
     */
    public static String unTarFile(File file,String outputDir,boolean isDelSource) {
        int buffersize = 2048;
        String basePath = file.getParent() + File.separator;
        TarArchiveInputStream is = null;
        try {
            is = new TarArchiveInputStream(new FileInputStream(file),"UTF-8");
            while (true) {
                TarArchiveEntry entry = is.getNextTarEntry();
                if (entry == null) {
                    break;
                }
                System.out.println("解压:"+entry.getName());
                if (entry.isDirectory()) {
                    // 一般不会执行
                    new File(outputDir, entry.getName()).mkdirs();
                } else {
                    FileOutputStream os = null;
                    try {
                        File tmpFile = new File(outputDir, entry.getName());
                        if (!tmpFile.getParentFile().exists()) {
                            tmpFile.getParentFile().mkdirs();
                        }
                        if (!tmpFile.exists()) {
                            tmpFile.createNewFile();
                        }
                        os = new FileOutputStream(tmpFile);
                        byte[] bs = new byte[buffersize];
                        int len = -1;
                        while ((len = is.read(bs)) != -1) {
                            os.write(bs, 0, len);
                        }
                        os.flush();
                    }
                    catch (Exception e) {
                        e.printStackTrace();
                    }
                    finally {
                        os.close();
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                is.close();
//                 解压后删除tar包
//                 file.delete();
            }
            catch (IOException e) {
                e.printStackTrace();
            }
        }
        if(isDelSource){
            file.delete();
        }
        // 返回tar包下所有文件名
        return outputDir;
    }

    /**
     * 压缩成ZIP
     * @param srcDir         压缩 文件/文件夹 路径
     * @param outPathFile    压缩 文件/文件夹 输出路径+文件名 D:/xx.zip
     * @param isDelSrcFile   是否删除原文件: 压缩前文件
     */
    public static File toZip(String srcDir, String outPathFile, boolean isDelSrcFile) throws Exception {
        long start = System.currentTimeMillis();
        FileOutputStream out = null;
        ZipOutputStream zos = null;
        File outFile = new File(outPathFile);
        try {
            out = new FileOutputStream(outFile);
            zos = new ZipOutputStream(out);
            File sourceFile = new File(srcDir);
            if(!sourceFile.exists()){
                throw new Exception("需压缩文件或者文件夹不存在");
            }
            File[] children = sourceFile.listFiles();
            if(children.length == 1){
                compress(children[0], zos, children[0].getName());
            } else {
                compress(sourceFile, zos, sourceFile.getName());
            }

//            log.info("原文件:{}. 压缩到:{}完成. 是否删除原文件:{}. 耗时:{}ms. ",srcDir,outPathFile,isDelSrcFile,System.currentTimeMillis()-start);
        } catch (Exception e) {
//            log.error("zip error from ZipUtils: {}. ",e.getMessage());
            throw new Exception("zip error from ZipUtils");
        } finally {
            try {
                if (zos != null) {zos.close();}
                if (out != null) {out.close();}
            } catch (Exception e) {}
        }
        if(isDelSrcFile){
            delDir(srcDir);
        }
        return outFile;
    }

    /**
     * 递归压缩方法
     * @param sourceFile 源文件
     * @param zos zip输出流
     * @param name 压缩后的名称
     */
    private static void compress(File sourceFile, ZipOutputStream zos, String name)
            throws Exception {
        byte[] buf = new byte[BUFFER_SIZE];
        if (sourceFile.isFile()) {
            zos.putNextEntry(new ZipEntry(name));
            int len;
            FileInputStream in = new FileInputStream(sourceFile);
            while ((len = in.read(buf)) != -1) {
                zos.write(buf, 0, len);
            }
            zos.closeEntry();
            in.close();
        } else {
            File[] listFiles = sourceFile.listFiles();
            if (listFiles == null || listFiles.length == 0) {
                if (KeepDirStructure) {
                    zos.putNextEntry(new ZipEntry(name + "/"));
                    zos.closeEntry();
                }
            } else {
                for (File file : listFiles) {
                    if (KeepDirStructure) {
                        compress(file, zos, name + "/" + file.getName());
                    } else {
                        compress(file, zos, file.getName());
                    }
                }
            }
        }
    }

    /**
     *
     * @Title: compressGZ
     * @Description: 将tar文件用gzip压缩
     * @param  source 需要压缩的文件
     * @return File    返回压缩后的文件
     * @throws
     */
    public static File compressGZ(File source, boolean isDelSrcFile) {
        File target = new File(source.getName() + ".gz");
        FileInputStream in = null;
        GZIPOutputStream out = null;
        try {
            in = new FileInputStream(source);
            out = new GZIPOutputStream(new FileOutputStream(target));
            byte[] array = new byte[1024];
            int number = -1;
            while((number = in.read(array, 0, array.length)) != -1) {
                out.write(array, 0, number);
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
            return null;
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        } finally {
            if(in != null) {
                try {
                    in.close();
                } catch (IOException e) {
                    e.printStackTrace();
                    return null;
                }
            }
            if(out != null) {
                try {
                    out.close();
                } catch (IOException e) {
                    e.printStackTrace();
                    return null;
                }
            }
        }
        try {
            if(isDelSrcFile){
                delDir(source.getAbsolutePath());
            }
        }catch (IOException e){
            e.printStackTrace();
        }
        return target;
    }


    /**
     *  压缩成tar
     * @param destFileName  带文件名输出文件全路径
     * @param files 要压缩的文件
     * @throws IOException
     */
    public static File tarFiles(String destFileName,boolean isDelSrcFile, File... files) throws IOException {
        File destFile = new File(destFileName);
        if (destFile.exists()) {
            org.apache.commons.io.FileUtils.forceDelete(destFile);
        }

        try (FileOutputStream fileOutputStream = new FileOutputStream(destFile);
             BufferedOutputStream bufferedWriter = new BufferedOutputStream(fileOutputStream);
             TarArchiveOutputStream tar = new TarArchiveOutputStream(bufferedWriter)) {

            tar.setLongFileMode(TarArchiveOutputStream.LONGFILE_GNU);

            for (File file : files) {
                addTarArchiveEntryToTarArchiveOutputStream(file, tar, "");
                if(isDelSrcFile){
                    delDir(file.getAbsolutePath());
                }
            }
        }
        return destFile;
    }

    private static void addTarArchiveEntryToTarArchiveOutputStream(File file, TarArchiveOutputStream tar,
                                                                   String prefix) throws IOException {
        TarArchiveEntry entry = new TarArchiveEntry(file, prefix + File.separator + file.getName());

        if (file.isFile()) {
            entry.setSize(file.length());
            tar.putArchiveEntry(entry);
            try (FileInputStream fileInputStream = new FileInputStream(file);
                 BufferedInputStream input = new BufferedInputStream(fileInputStream);) {
                IOUtils.copy(input, tar);
            }
            tar.closeArchiveEntry();
        } else {
            tar.putArchiveEntry(entry);
            tar.closeArchiveEntry();
            prefix += File.separator + file.getName();
            File[] files = file.listFiles();
            if (files != null) {
                for (File f : files) {
                    addTarArchiveEntryToTarArchiveOutputStream(f, tar, prefix);
                }
            }
        }
    }

    // 删除文件或文件夹以及文件夹下所有文件
    public static void delDir(String dirPath) throws IOException {
//        log.info("删除文件开始:{}.",dirPath);
        try{
            File dirFile = new File(dirPath);
            if (!dirFile.exists()) {
                return;
            }
            if (dirFile.isFile()) {
                dirFile.delete();
                System.out.println("删除"+dirFile.getAbsolutePath());
                return;
            }
            File[] files = dirFile.listFiles();
            if(files==null){
                return;
            }
            for (int i = 0; i < files.length; i++) {
                delDir(files[i].toString());
            }
            dirFile.delete();
            System.out.println("删除"+dirFile.getAbsolutePath());
//            log.info("删除文件:{}. 耗时:{}ms. ",dirPath,System.currentTimeMillis()-start);
        }catch(Exception e){
//            log.info("删除文件:{}. 异常:{}. 耗时:{}ms. ",dirPath,e,System.currentTimeMillis()-start);
            throw new IOException("删除文件异常.");
        }
    }
}

你可能感兴趣的:(java)