文件压缩解压

1、maven依赖

<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-compress</artifactId>
    <version>1.21</version>
</dependency>

2、压缩解压类

   压缩:按某种算法减小文件所占用空间的大小
    解压:按对应的逆向算法恢复文件

   GzipCompressorOutputStream:压缩"*.gz"文件
    GzipCompressorInputStream:解压"*.gz"文件
    BZip2CompressorOutputStream:压缩"*.bz2"文件
    BZip2CompressorInputStream:解压"*.bz2"文件
    XZCompressorOutputStream:压缩"*.xz"文件
    XZCompressorInputStream:解压"*.xz"文件
    FramedLZ4CompressorOutputStream:压缩"*.lz4"文件
    FramedLZ4CompressorInputStream:解压"*.lz4"文件
    BlockLZ4CompressorOutputStream:压缩"*.block_lz4"文件
    BlockLZ4CompressorInputStream:解压"*.block_lz4"文件
    Pack200CompressorOutputStream:压缩"*.pack"文件
    Pack200CompressorInputStream:解压"*.pack"文件
    DeflateCompressorOutputStream:压缩"*.deflate"文件
    DeflateCompressorInputStream:解压"*.deflate"文件
    LZMACompressorOutputStream:压缩"*.lzma"文件
    LZMACompressorInputStream:解压"*.lzma"文件
    FramedSnappyCompressorOutputStream:压缩"*.sz"文件
    FramedSnappyCompressorInputStream:解压"*.sz"文件
    ZCompressorInputStream:解压"*.Z"文件

3、 gzip压缩及解压实例

// gzip压缩
    String file = "/test.js";
    GzipParameters parameters = new GzipParameters();
    parameters.setCompressionLevel(Deflater.BEST_COMPRESSION);
    parameters.setOperatingSystem(3);
    parameters.setFilename(FilenameUtils.getName(file));
    parameters.setComment("Test file");
    parameters.setModificationTime(System.currentTimeMillis());
    FileOutputStream fos = new FileOutputStream(file + ".gz");
    try (GzipCompressorOutputStream gzos = new GzipCompressorOutputStream(fos, parameters);
         InputStream is = new FileInputStream(file)) {
        IOUtils.copy(is, gzos);
    }

// gzip解压
    String gzFile = "/test.js.gz";
    FileInputStream is = new FileInputStream(gzFile);
    try (GzipCompressorInputStream gis = new GzipCompressorInputStream(is)) {
        GzipParameters p = gis.getMetaData();
        File targetFile = new File("/test.js");
        FileUtils.copyToFile(gis, targetFile);
        targetFile.setLastModified(p.getModificationTime());
    }


4、bz2压缩及解压实例

// 压缩bz2
    String srcFile = "/test.tar";
    String targetFile = "/test.tar.bz2";
    FileOutputStream os = new FileOutputStream(targetFile);
    try (BZip2CompressorOutputStream bzos = new BZip2CompressorOutputStream(os);
         InputStream is = new FileInputStream(srcFile)) {
        IOUtils.copy(is, bzos);
    }
// 解压bz2
    String bzFile = "/test.tar.bz2";
    FileInputStream is = new FileInputStream(bzFile);
    try (BZip2CompressorInputStream bzis = new BZip2CompressorInputStream(is)) {
        File targetFile = new File("test.tar");
        FileUtils.copyToFile(bzis, targetFile);
    }

5、归档解包类

    归档:将许多零散的文件整理为一个文件,文件总大小基本不变
    解包:从归档文件中释放文件

    TarArchiveOutputStream:归档"*.tar"文件
    TarArchiveInputStream:解包"*.tar"文件
    ZipArchiveOutputStream:归档压缩"*.zip"文件
    ZipArchiveInputStream:解包解压"*.zip"文件
    JarArchiveOutputStream:归档压缩"*.jar"文件
    JarArchiveInputStream:解包解压"*.jar"文件
    DumpArchiveOutputStream:归档"*.dump"文件
    DumpArchiveInputStream:解包"*.dump"文件
    CpioArchiveOutputStream:归档压缩"*.cpio"文件
    CpioArchiveInputStream:解包解压"*.cpio"文件
    ArArchiveOutputStream:归档压缩"*.ar"文件
    ArArchiveInputStream:解包解压"*.ar"文件
    ArjArchiveInputStream:解包解压"*.arj"文件
    SevenZOutputFile:归档压缩"*.7z"文件
    SevenZFile:解包解压"*.7z"文件

6、tar归档解包实例

// tar压缩
    public void tar() throws IOException {
        File srcDir = new File("/test");
        String targetFile = "/test.tar";
        try (TarArchiveOutputStream tos = new TarArchiveOutputStream(
                new FileOutputStream(targetFile))) {
            tarRecursive(tos, srcDir, "");
        }
    }
// 递归压缩目录下的文件和目录
    private void tarRecursive(TarArchiveOutputStream tos, File srcFile, String basePath) throws IOException {
        if (srcFile.isDirectory()) {
            File[] files = srcFile.listFiles();
            String nextBasePath = basePath + srcFile.getName() + "/";
            if (ArrayUtils.isEmpty(files)) {
                // 空目录
                TarArchiveEntry entry = new TarArchiveEntry(srcFile, nextBasePath);
                tos.putArchiveEntry(entry);
                tos.closeArchiveEntry();
            } else {
                for (File file : files) {
                    tarRecursive(tos, file, nextBasePath);
                }
            }
        } else {
            TarArchiveEntry entry = new TarArchiveEntry(srcFile, basePath + srcFile.getName());
            tos.putArchiveEntry(entry);
            FileUtils.copyFile(srcFile, tos);
            tos.closeArchiveEntry();
        }
    }

// tar解压
    public void untar() throws IOException {
        InputStream is = new FileInputStream("/test.tar");
        String outPath = "/test";
        try (TarArchiveInputStream tis = new TarArchiveInputStream(is)) {
            TarArchiveEntry nextEntry;
            while ((nextEntry = tis.getNextTarEntry()) != null) {
                String name = nextEntry.getName();
                File file = new File(outPath, name);
                //如果是目录,创建目录
                if (nextEntry.isDirectory()) {
                    file.mkdir();
                } else {
                    //文件则写入具体的路径中
                    FileUtils.copyToFile(tis, file);
                    file.setLastModified(nextEntry.getLastModifiedDate().getTime());
                }
            }
        }
    }

7、修改归档文件

String tarFile = "/test.tar";
    InputStream is = new FileInputStream(tarFile);
    // 替换后会覆盖原test.tar,如果是windows可能会由于文件被访问而覆盖报错
    OutputStream os = new FileOutputStream(tarFile);
    try (TarArchiveInputStream tais = new TarArchiveInputStream(is);
         TarArchiveOutputStream taos = new TarArchiveOutputStream(os)) {
        ChangeSet changes = new ChangeSet();
        // 删除"test.tar中"的"dir/1.txt"文件
        changes.delete("dir/1.txt");
        // 删除"test.tar"中的"t"目录
        changes.delete("t");
        // 添加文件,如果已存在则替换
        File addFile = new File("/a.txt");
        ArchiveEntry addEntry = taos.createArchiveEntry(addFile, addFile.getName());
        // add可传第三个参数:true: 已存在则替换(默认值), false: 不替换
        changes.add(addEntry, new FileInputStream(addFile));
        // 执行修改
        ChangeSetPerformer performer = new ChangeSetPerformer(changes);
        ChangeSetResults result = performer.perform(tais, taos);

8、其他

//1. 简单工厂
// 使用factory动态获取归档流
    ArchiveStreamFactory factory = new ArchiveStreamFactory();
    String archiveName = ArchiveStreamFactory.TAR;
    InputStream is = new FileInputStream("/in.tar");
    OutputStream os = new FileOutputStream("/out.tar");
    // 动态获取实现类,此时ais实际上是TarArchiveOutPutStream
    ArchiveInputStream ais = factory.createArchiveInputStream(archiveName, is);
    ArchiveOutputStream aos = factory.createArchiveOutputStream(archiveName, os);
    // 其他业务操作

    // 使用factory动态获取压缩流
    CompressorStreamFactory factory = new CompressorStreamFactory();
    String compressName = CompressorStreamFactory.GZIP;
    InputStream is = new FileInputStream("/in.gz");
    OutputStream os = new FileOutputStream("/out.gz");
    // 动态获取实现类,此时ais实际上是TarArchiveOutPutStream
    CompressorInputStream cis = factory.createCompressorInputStream(compressName, is);
    CompressorOutputStream cos = factory.createCompressorOutputStream(compressName, os);
    // 其他业务操作


//2. 同时解压解包
// 解压 解包test.tar.gz文件
    String outPath = "/test";
    InputStream is = new FileInputStream("/test.tar.gz");
    // 先解压,所以需要先用gzip流包装文件流
    CompressorInputStream gis = new GzipCompressorInputStream(is);
    // 在解包,用tar流包装gzip流
    try (ArchiveInputStream tgis = new TarArchiveInputStream(gis)) {
        ArchiveEntry nextEntry;
        while ((nextEntry = tgis.getNextEntry()) != null) {
            String name = nextEntry.getName();
            File file = new File(outPath, name);
            // 如果是目录,创建目录
            if (nextEntry.isDirectory()) {
                file.mkdir();
            } else {
                // 文件则写入具体的路径中
                FileUtils.copyToFile(tgis, file);
                file.setLastModified(nextEntry.getLastModifiedDate().getTime());
            }
        }
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值