美文网首页
java利用commons-compress压缩解压缩targz

java利用commons-compress压缩解压缩targz

作者: haiyong6 | 来源:发表于2021-11-28 13:55 被阅读0次

    介绍

    Apache Commons Compress 是apache下可以用来对文件解压缩的一个项目,官网示例介绍:https://commons.apache.org/proper/commons-compress/examples.html

    摘一下支持的格式描述:

    "Commons Compress调用压缩单个数据流压缩格式的所有格式,而在单个(可能已压缩)存档中收集多个条目的所有格式都是archiver格式。

    支持的压缩格式有gzip、bzip2、xz、lzma、Pack200、DEFLATE、Brotli、DEFLATE64、ZStandard和Z,归档格式有7z、ar、arj、cpio、dump、tar和zip。Pack200是一种特殊情况,因为它只能压缩JAR文件。

    我们目前只提供对arj、dump、Brotli、DEFLATE64和Z的读取支持。arj只能读取未压缩的归档文件,7z可以读取7z支持的许多压缩和加密算法的归档文件,但在写入归档文件时不支持加密。"
    可以到commons-compress很强大,在官方示例里可以找到tar和gzip的示例描述如下:


    tar示例实现描述
    gzip示例实现描述

    压缩思路

    1.先把需要压缩的文件或文件夹,打包成.tar文件。
    2.使用gzip把刚刚打包的.tar文件进行压缩(tar.gz)

    解压缩思路

    1.把tar.gz先解压成tar
    2.把tar解压成文件或文件夹

    引入common-compress

    去maven仓库搜索common-compress,截止发文最新版本是1.21
    gradle引入:

    compile("org.apache.commons:commons-compress:1.21")
    

    实现代码

    创建DecompressionUtil

    package com.ly.mp.project.utils;
    
    import java.io.BufferedInputStream;
    import java.io.BufferedOutputStream;
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.FileOutputStream;
    import java.io.IOException;
    
    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.compress.compressors.gzip.GzipCompressorInputStream;
    import org.apache.commons.compress.compressors.gzip.GzipCompressorOutputStream;
    
    /**
     * 解压缩
     * @author zhaohy
     *
     */
    public class DecompressionUtil {
        /**
         * 归档
         * @param entry
         * @return 
         */
        private static String archive(String path) throws Exception {
            File file = new File(path);
    
            FileOutputStream fos = null;
            TarArchiveOutputStream tos = null;
            String baseName = file.getName();
            String tarName = file.getAbsolutePath() + ".tar";
            try {
                fos = new FileOutputStream(tarName);
                tos = new TarArchiveOutputStream(fos);
                
                if(file.isDirectory()){
                    archiveDir(file, tos, baseName);
                }else{
                    archiveHandle(tos, file, baseName);
                }
            } catch (Exception e) {
                throw e;
            } finally {
                try {
                    tos.close();
                    fos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            
            return tarName;
        }
    
        /**
         * 递归处理,准备好路径
         * @param file
         * @param tos
         * @param base 
         */
        private static void archiveDir(File file, TarArchiveOutputStream tos, String basePath) throws Exception {
            File[] listFiles = file.listFiles();
            for(File fi : listFiles){
                if(fi.isDirectory()){
                    archiveDir(fi, tos, basePath + File.separator + fi.getName());
                }else{
                    archiveHandle(tos, fi, basePath);
                }
            }
        }
    
        /**
         * 具体归档处理(文件)
         * @param tos
         * @param fi
         * @param base
         */
        private static void archiveHandle(TarArchiveOutputStream tos, File fi, String basePath) throws Exception {
            TarArchiveEntry tEntry = new TarArchiveEntry(basePath + File.separator + fi.getName());
            tEntry.setSize(fi.length());
    
            tos.putArchiveEntry(tEntry);
            FileInputStream fis = null;
            BufferedInputStream bis = null;
            try {
                fis = new FileInputStream(fi);
                bis = new BufferedInputStream(fis);
                byte[] buffer = new byte[1024];
                int read = -1;
                while((read = bis.read(buffer)) != -1){
                    tos.write(buffer, 0 , read);
                }
            } catch (Exception e) {
                throw e;
            } finally {
                try {
                    bis.close();
                    fis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
           
            tos.closeArchiveEntry();//这里必须写,否则会失败
        }
        
        /**
         * 把tar包压缩成gz
         * @param path
         * @throws IOException
         * @return 
         */
        public static String compressArchive(String path) throws IOException{
            BufferedInputStream bis = new BufferedInputStream(new FileInputStream(path));
    
            GzipCompressorOutputStream gcos = new GzipCompressorOutputStream(new BufferedOutputStream(new FileOutputStream(path + ".gz")));
    
            byte[] buffer = new byte[1024];
            int read = -1;
            while((read = bis.read(buffer)) != -1){
                gcos.write(buffer, 0, read);
            }
            gcos.close();
            bis.close();
            return path + ".gz";
        }
        
        /**
         * 解压成tar
         * @param archive
         */
        public static Boolean unCompressTargz(String gzPath) throws Exception {
            Boolean flag = true;
            
            File file = new File(gzPath);
    
            String fileName = file.getName().substring(0, file.getName().lastIndexOf("."));
            String finalName = file.getParent() + File.separator + fileName;
            
            FileInputStream fis = null;
            BufferedInputStream bis = null;
            FileOutputStream fos = null;
            BufferedOutputStream bos = null;
            GzipCompressorInputStream gcis = null;
            try {
                fis = new FileInputStream(file);
                bis = new BufferedInputStream(fis);
                fos = new FileOutputStream(finalName);
                bos = new BufferedOutputStream(fos);
                gcis = new GzipCompressorInputStream(bis);
                byte[] buffer = new byte[1024];
                int read = -1;
                while((read = gcis.read(buffer)) != -1){
                    bos.write(buffer, 0, read);
                }
            } catch (Exception e) {
                flag = false;
                //throw e;
            } finally {
                try {
                    gcis.close();
                    bos.close();
                    fos.close();
                    bis.close();
                    fis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if(flag) flag = unCompressTar(finalName);
            file = new File(finalName);
            file.delete();//删除tar文件
            return flag;
        }
        
        /**
         * 解压tar
         * @param finalName
         * @throws IOException 
         */
        private static Boolean unCompressTar(String finalName) throws Exception {
            Boolean flag = true;
            File file = new File(finalName);
            String parentPath = file.getParent();
            
            FileInputStream fis = null;
            TarArchiveInputStream tais = null;
            try {
                fis = new FileInputStream(file);
                tais = new TarArchiveInputStream(fis);
                TarArchiveEntry tarArchiveEntry = null;
                while((tarArchiveEntry = tais.getNextTarEntry()) != null){
                     String name = tarArchiveEntry.getName();
                     File tarFile = new File(parentPath, name);
                     if(!tarFile.getParentFile().exists()){
                         tarFile.getParentFile().mkdirs();
                     }
    
                     FileOutputStream fos = null;
                     BufferedOutputStream bos = null;
                     try {
                         fos = new FileOutputStream(tarFile);
                         bos = new BufferedOutputStream(fos);
                         int read = -1;
                         byte[] buffer = new byte[1024];
                         while((read = tais.read(buffer)) != -1){
                             bos.write(buffer, 0, read);
                         }
                    } catch (Exception e) {
                        throw e;
                    } finally {
                        bos.close();
                        fos.close();
                    }
                 }
            } catch (Exception e) {
                flag = false;
                throw e;
            } finally {
                try {
                    fis.close();
                    tais.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                
            }
            return flag;
        }
        
        public static String compressToTargz(String path) throws Exception {
            //生成tar包
            String tarPath = archive(path);
            String gzPath = compressArchive(tarPath);//生成gz包
            File file = new File(tarPath);
            file.delete();//删除tar文件
            return gzPath;
        }
        
        public static void main(String[] args) {
            String path = "D:\\test\\compress";//需要压缩的文件夹
            try {
                //压缩
    //          System.out.println(compressToTargz(path));
                
                //解压
                System.out.println(unCompressTargz("D:\\test\\compress.tar.gz"));  
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
    

    如上代码所示,运行main方法可以测试tar.gz的压缩和解压缩效果,实测没什么问题。

    参考:https://blog.csdn.net/u013066244/article/details/72783575

    相关文章

      网友评论

          本文标题:java利用commons-compress压缩解压缩targz

          本文链接:https://www.haomeiwen.com/subject/rbncxrtx.html