Java实现zip、tar、tar.gz 打包压缩解压

什么是zip

zip是一种数据压缩和文档储存的文件格式,原名Deflate,发明者为菲尔·卡茨(Phil Katz),他于1989年1月公布了该格式的资料。ZIP通常使用后缀名“.zip”,它的MIME格式为application/zip。当前,ZIP格式属于几种主流的压缩格式之一,其竞争者包括RAR格式以及开放源码的7z格式。从性能上比较,RAR及7z格式较ZIP格式压缩率较高,而7-Zip由于提供了免费的压缩工具而逐渐在更多的领域得到应用。Microsoft从Windows ME操作系统开始内置对zip格式的支持,即使用户的计算机上没有安装解压缩软件,也能打开和制作zip格式的压缩文件,OS X和流行的Linux操作系统也对zip格式提供了类似的支持。因此如果在网络上传播和分发文件,zip格式往往是最常用的选择。

ZIP是一种相当简单的分别压缩每个文件的存档格式。分别压缩文件允许不必读取另外的数据而检索独立的文件;理论上,这种格式允许对不同的文件使用不同的算法。不管用何种方法,对这种格式的一个告诫是对于包含很多小文件的时候,存档会明显的比压缩成一个独立的文件(在类Unix系统中一个经典的例子是普通的tar.gz存档是由一个使用gzip压缩的TAR存档组成)要大.

什么是tar

tar是UNIX/Linux系统上的压缩文件格式,tar文件则是一种压缩文件,在Linux系统中可以直接解压使用这种压缩文件。在Windows下也可以使用WinRAR等常见的解压缩软件打开。tar其实就相当于常见的rar和zip格式。

什么是tar.gz

以.tar.gz为扩展名的是一种压缩文件,在Linux和OSX下常见,Linux和OSX都可以直接解压使用这种压缩文件。windows下的WinRAR也可以使用。相当于常见的RAR和ZIP格式

总结

  • zip 和tar.gz 都属于压缩文件,文件大小肯定压缩前小
  • tar 只是属于打包文件 文件大小不会变小有可能更大

实现代码

package com.bj.drj;

import cn.hutool.core.lang.Console;
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.archivers.zip.ZipArchiveEntry;
import org.apache.commons.compress.archivers.zip.ZipArchiveInputStream;
import org.apache.commons.compress.archivers.zip.ZipArchiveOutputStream;
import org.apache.commons.compress.compressors.gzip.GzipCompressorInputStream;
import org.apache.commons.compress.compressors.gzip.GzipCompressorOutputStream;
import org.apache.commons.io.IOUtils;

import java.io.*;

/**
 * @ClassName PackAndCompressionUtils
 * @Description: 解压压缩文件
 * @Author drj
 * @Date 2021/9/18
 * @Version V1.0
 **/
public class PackAndCompressionUtils {


    private PackAndCompressionUtils() {
    }

    /**
     * 这个方法主要针对文件实现打包tar 也可以生成tar.gz 但是失去了gz 压缩功能 只是现实了打包。
     *
     * @param filesPathArray 需要打包的文件
     * @param targetDirPath  生成tar 目录
     * @return
     * @throws Exception
     */
    public static boolean tarPack(String[] filesPathArray, String targetDirPath) throws Exception {
        try (FileOutputStream fileOutputStream = new FileOutputStream(new File(targetDirPath));
             BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(fileOutputStream);
             TarArchiveOutputStream tarArchiveOutputStream = new TarArchiveOutputStream(bufferedOutputStream)) {
            for (String filePath : filesPathArray) {
                try (FileInputStream fileInputStream = new FileInputStream(new File(filePath))) {
                    File file = new File(filePath);
                    TarArchiveEntry tae = new TarArchiveEntry(file, file.getName());
                    tarArchiveOutputStream.putArchiveEntry(tae);
                    IOUtils.copy(fileInputStream, tarArchiveOutputStream);
                    tarArchiveOutputStream.closeArchiveEntry();
                } catch (Exception e) {
                    Console.error(e, "异常信息:{}", filePath);
                }
            }
        } catch (Exception e) {
            Console.error(e, "异常信息:{}", filesPathArray);
        }
        return true;
    }

    /**
     * 解压打包文件
     *
     * @param unPackFilePath
     * @param targetDirPath
     * @return
     * @throws Exception
     */
    public static boolean tarUnpack(String unPackFilePath, String targetDirPath) throws Exception {
        try (FileInputStream fileInputStream = new FileInputStream(new File(unPackFilePath));
             TarArchiveInputStream tarArchiveInputStream = new TarArchiveInputStream(fileInputStream)) {
            TarArchiveEntry tae = null;
            while ((tae = tarArchiveInputStream.getNextTarEntry()) != null) {
                String dir = targetDirPath + File.separator + tae.getName();
                try (FileOutputStream fileOutputStream = new FileOutputStream(new File(dir));
                     BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(fileOutputStream)) {
                    IOUtils.copy(tarArchiveInputStream, bufferedOutputStream);
                } catch (Exception ex) {
                    Console.error(ex, "异常文件:{}", dir);
                }
            }
        } catch (Exception ex) {
            Console.error(ex, "异常文件:{}", unPackFilePath);
        }
        return true;
    }

    /**
     * gzip压缩文件 后缀是.gz
     *
     * @param filesPathArray
     * @param targetDirPath
     * @return
     * @throws IOException
     */
    public static boolean gzipCompress(String[] filesPathArray, String targetDirPath) throws IOException {
        try (OutputStream outputStream = new FileOutputStream(new File(targetDirPath));
             GzipCompressorOutputStream gzipCompressorOutputStream = new GzipCompressorOutputStream(outputStream)) {
            for (String filePath : filesPathArray) {
                try (InputStream inputStream = new FileInputStream(new File(filePath));) {
                    TarArchiveOutputStream tarArchiveOutputStream = new TarArchiveOutputStream(gzipCompressorOutputStream);
                    File file = new File(filePath);
                    TarArchiveEntry archiveEntry = new TarArchiveEntry(file, file.getName());
                    tarArchiveOutputStream.putArchiveEntry(archiveEntry);
                    IOUtils.copy(inputStream, tarArchiveOutputStream);
                    tarArchiveOutputStream.closeArchiveEntry();
                } catch (Exception ex) {
                    Console.error(ex, "异常文件:{}", filePath);
                }
            }

        } catch (Exception ex) {
            Console.error(ex, "异常文件:{}", filesPathArray);
        }

        return true;
    }


    /**
     * 针对gz包 进行解压
     *
     * @param sourceDir
     * @param targetDirPath
     */
    public static boolean gzipDeCompress(String sourceDir, String targetDirPath) {
        try (
                FileInputStream fileInputStream = new FileInputStream(sourceDir);
                GzipCompressorInputStream gzipCompressorInputStream = new GzipCompressorInputStream(fileInputStream);
                TarArchiveInputStream tarArchiveInputStream = new TarArchiveInputStream(gzipCompressorInputStream);
        ) {
            TarArchiveEntry tarArchiveEntry = null;
            while ((tarArchiveEntry = tarArchiveInputStream.getNextTarEntry()) != null) {
                String dir = targetDirPath + File.separator + tarArchiveEntry.getName();
                try (FileOutputStream fileOutputStream = new FileOutputStream(new File(dir))) {
                    IOUtils.copy(tarArchiveInputStream, fileOutputStream);
                } catch (Exception ex) {
                    Console.error(ex, "异常文件路径:{}", sourceDir);
                }
            }

        } catch (Exception ex) {
            Console.error(ex, "异常文件路径:{}", sourceDir);
        }
        return true;
    }


    /**
     * 对文件进行zip打包处理
     *
     * @param filesPathArray
     * @param targetDirPath
     * @return
     * @throws Exception
     */
    public static boolean zipCompress(String[] filesPathArray, String targetDirPath) throws Exception {
        try (FileOutputStream fileOutputStream = new FileOutputStream(new File(targetDirPath));
             ZipArchiveOutputStream zipArchiveOutputStream = new ZipArchiveOutputStream(fileOutputStream)) {

            for (String filePath : filesPathArray) {
                try (FileInputStream fileInputStream = new FileInputStream(new File(filePath))) {
                    File file = new File(filePath);
                    ZipArchiveEntry zae = new ZipArchiveEntry(file, file.getName());
                    zipArchiveOutputStream.putArchiveEntry(zae);
                    IOUtils.copy(fileInputStream, zipArchiveOutputStream);
                    zipArchiveOutputStream.closeArchiveEntry();
                } catch (Exception ex) {
                    Console.error(ex, "异常文件路径:{}", filePath);
                }

            }
        } catch (Exception ex) {
            Console.error(ex, "异常文件路径:{}", filesPathArray);
        }
        return true;
    }


    /**
     * 解压zip 文件
     *
     * @param decompressFilePath
     * @param targetDirPath
     * @return
     * @throws Exception
     */
    public static boolean zipDecompress(String decompressFilePath, String targetDirPath) throws Exception {

        try (FileInputStream fileInputStream = new FileInputStream(new File(decompressFilePath));
             ZipArchiveInputStream zipArchiveInputStream = new ZipArchiveInputStream(fileInputStream)) {
            ZipArchiveEntry zae = null;
            while ((zae = zipArchiveInputStream.getNextZipEntry()) != null) {
                String dir = targetDirPath + File.separator + zae.getName();
                try (FileOutputStream fileOutputStream = new FileOutputStream(new File(dir))) {
                    IOUtils.copy(zipArchiveInputStream, fileOutputStream);
                } catch (Exception ex) {
                    Console.error(ex, "异常文件路径:{}", dir);
                }
            }
        } catch (Exception ex) {
            Console.error(ex, "异常文件路径:{}", decompressFilePath);
        }
        return true;
    }

}

单元测试

    String[] filesPathArray = new String[]{"D:\\core\\a.txt", "D:\\core\\b.txt"};
    String[] fileTarPath = new String[]{"D:\\core\\tarcompress.tar"};
    String compressTarTargetDirPath = "D:\\core\\tarcompress.tar.gz";
    String compressZipTargetDirPath = "D:\\core\\tarcompress.zip";
    String compressGzTargetDirPath = "D:\\core\\tarcompress3.gz";
    String compressGzTargetDirPath4 = "D:\\core\\tarcompress4.gz";
    String deCompressDirPath = "D:\\core";

    @Test
    public void testTarPack() throws Exception {
        boolean b = PackAndCompressionUtils.tarPack(filesPathArray, compressTarTargetDirPath);
        Assert.assertTrue(b);
    }

    @Test
    public void testTarUnpack() throws Exception {
        boolean b = PackAndCompressionUtils.tarUnpack(compressGzTargetDirPath, deCompressDirPath);
        Assert.assertTrue(b);
    }

    @Test
    public void testZipCompress() throws Exception {
        boolean b = PackAndCompressionUtils.zipCompress(filesPathArray, compressZipTargetDirPath);
        Assert.assertTrue(b);
    }

    @Test
    public void testZipDeCompress() throws Exception {
        boolean b = PackAndCompressionUtils.zipDecompress(compressZipTargetDirPath, deCompressDirPath);
        Assert.assertTrue(b);
    }

    @Test
    public void test() throws Exception {
        MyUnTarGzUtil.unTarGz(compressGzTargetDirPath,deCompressDirPath);
    }


    @Test
    public void testGzCompress() throws Exception {
        boolean b = PackAndCompressionUtils.gzipCompress(filesPathArray, compressGzTargetDirPath4);
        Assert.assertTrue(b);
    }

    @Test
    public void testGzDeCompress() throws Exception {
        boolean b = PackAndCompressionUtils.gzipDeCompress(compressTarTargetDirPath, deCompressDirPath);
        Assert.assertTrue(b);
    }
上一篇:如何详细的处理异常


下一篇:1、用datetimepicker插件实现限定时间范围的选择 2、时间插件实现默认当天的时间和只能选择小于今天的日期