Java主流压缩解压工具对比、用法与选取详解

 更新时间:2024年01月29日 09:15:36   作者:麦神-mirson  
开发过程中可能会用到压缩文件的需求,下面这篇文章主要给大家介绍了关于Java主流压缩解压工具对比、用法与选取的相关资料,文中通过代码介绍的非常详细,需要的朋友可以参考下

一、JAVA主流压缩工具

  • java.util.zip:

    **说明:**Java标准库提供的压缩与解压功能,包含在java.util.zip包中。通过ZipInputStreamZipOutputStream可以实现ZIP格式的压缩与解压缩操作。

    适用场景: 适合简单的ZIP格式压缩与解压缩操作,可用于对单个文件或目录进行压缩和解压缩。

  • Apache Commons Compress:

    **说明:**Apache Commons Compress是Apache软件基金会提供的开源压缩与解压工具包,支持多种压缩格式,包括ZIP、Gzip、Tar等。通过该工具包,可以进行更复杂的压缩与解压缩操作。

    **适用场景:**支持多种压缩格式,如ZIP、Gzip、Tar等,适合复杂的压缩与解压缩操作,可用于处理各种压缩格式和对多个文件或目录进行打包、解压缩。

  • Java Zip4j:

    **说明:**Zip4j是一个开源的Java库,提供了对ZIP格式的支持,并且支持密码保护、分卷压缩等功能。

    **适用场景:**支持ZIP格式,提供了一些高级功能,如密码保护、分卷压缩等,适合复杂的ZIP格式的压缩与解压缩操作。

  • LZ4:

    **说明:**LZ4是一种高性能的压缩算法,具有快速的压缩和解压缩速度,但压缩比相对较低。

    **适用场景:**适合对大量数据进行实时压缩和解压缩,例如在网络传输或大数据处理中,追求较高的压缩/解压缩速度。

  • Snappy

    **说明:**Snappy是一种快速的压缩和解压缩算法,具有较快的压缩和解压缩速度,适合高性能场景。

    **适用场景:**适用于对大规模数据进行实时压缩和解压缩,例如在大数据处理和分析中。

这些压缩与解压工具可以根据项目的需求和使用场景选择合适的工具进行压缩与解压缩操作。Java标准库的java.util.zip包通常适用于简单的ZIP格式压缩与解压缩,Apache Commons Compress和Java Zip4j提供了更多的压缩格式和功能选项。对于大型数据集和高性能要求的场景,还可以考虑使用专门的压缩工具或算法,如LZ4、Snappy等。

二、压缩与解压用法

  • java.util.zip的使用

    import java.io.*;
    import java.util.zip.ZipEntry;
    import java.util.zip.ZipInputStream;
    import java.util.zip.ZipOutputStream;
    
    public class JavaUtilZipDemo {
    
        /**
         * 使用java.util.zip库进行文件压缩
         *
         * @param inputFile  要压缩的文件或目录
         * @param outputFile 压缩后的文件
         * @throws IOException 压缩过程中可能出现的异常
         */
        public static void zipCompress(File inputFile, File outputFile) throws IOException {
            // 创建输出流写入压缩后的文件
            try (ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(outputFile))) {
                // 判断要压缩的是文件还是目录
                if (inputFile.isFile()) {
                    // 压缩文件
                    zipFile(inputFile, zos, "");
                } else if (inputFile.isDirectory()) {
                    // 压缩目录
                    zipDir(inputFile, zos, "");
                }
            }
        }
    
        /**
         * 递归压缩目录及其子目录和文件
         *
         * @param dir   要压缩的目录
         * @param zos   压缩输出流
         * @param entry 压缩实体
         * @throws IOException 压缩过程中可能出现的异常
         */
        private static void zipDir(File dir, ZipOutputStream zos, String entry) throws IOException {
            // 获取目录中的文件和子目录
            File[] files = dir.listFiles();
            if (files != null) {
                for (File file : files) {
                    if (file.isFile()) {
                        // 压缩文件
                        zipFile(file, zos, entry + file.getName());
                    } else if (file.isDirectory()) {
                        // 压缩子目录
                        zipDir(file, zos, entry + file.getName() + "/");
                    }
                }
            }
        }
    
        /**
         * 压缩文件
         *
         * @param file  要压缩的文件
         * @param zos   压缩输出流
         * @param entry 压缩实体
         * @throws IOException 压缩过程中可能出现的异常
         */
        private static void zipFile(File file, ZipOutputStream zos, String entry) throws IOException {
            // 创建压缩实体并设置实体名称
            ZipEntry zipEntry = new ZipEntry(entry);
            // 将压缩实体写入压缩输出流
            zos.putNextEntry(zipEntry);
    
            // 创建输入流读取文件内容,并将内容写入压缩输出流
            try (FileInputStream fis = new FileInputStream(file)) {
                byte[] buffer = new byte[1024];
                int length;
                while ((length = fis.read(buffer)) > 0) {
                    zos.write(buffer, 0, length);
                }
            }
    
            // 关闭当前压缩实体
            zos.closeEntry();
        }
    
        /**
         * 使用java.util.zip库进行文件解压缩
         *
         * @param inputFile 压缩文件
         * @param outputDir 解压后的目录
         * @throws IOException 解压过程中可能出现的异常
         */
        public static void zipDecompress(File inputFile, File outputDir) throws IOException {
            // 创建输入流读取压缩文件
            try (ZipInputStream zis = new ZipInputStream(new FileInputStream(inputFile))) {
                // 遍历压缩文件中的实体
                ZipEntry zipEntry;
                while ((zipEntry = zis.getNextEntry()) != null) {
                    // 获取实体的名称
                    String entryName = zipEntry.getName();
                    // 创建输出文件并设置输出目录
                    File outputFile = new File(outputDir, entryName);
    
                    // 如果实体是目录,则创建相应目录;否则创建输出文件并写入数据
                    if (zipEntry.isDirectory()) {
                        outputFile.mkdirs();
                    } else {
                        try (FileOutputStream fos = new FileOutputStream(outputFile)) {
                            // 将输入流的数据写入输出文件
                            byte[] buffer = new byte[1024];
                            int length;
                            while ((length = zis.read(buffer)) > 0) {
                                fos.write(buffer, 0, length);
                            }
                        }
                    }
    
                    // 关闭当前解压实体
                    zis.closeEntry();
                }
            }
        }
    
        public static void main(String[] args) {
            try {
                File inputFile = new File("input");
                File outputFile = new File("output.zip");
                File outputDir = new File("output");
    
                // 压缩文件或目录
                zipCompress(inputFile, outputFile);
    
                // 解压缩文件
                zipDecompress(outputFile, outputDir);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
  • Apache Commons Compress的使用

    import org.apache.commons.compress.archivers.ArchiveEntry;
    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;
    import org.apache.commons.compress.utils.IOUtils;
    
    import java.io.*;
    
    public class CommonsCompressUtil {
        /**
         * 使用 Apache Commons Compress 库进行Gzip压缩
         *
         * @param inputFile  要压缩的文件
         * @param outputFile 压缩后的文件
         * @throws IOException 压缩过程中可能出现的异常
         */
        public static void gzipCompress(File inputFile, File outputFile) throws IOException {
            // 创建输入流读取要压缩的文件
            try (FileInputStream fis = new FileInputStream(inputFile);
                 // 创建压缩输出流写入压缩后的文件
                 GzipCompressorOutputStream gzos = new GzipCompressorOutputStream(new FileOutputStream(outputFile))) {
                // 将输入流的数据压缩并写入输出流
                IOUtils.copy(fis, gzos);
            }
        }
    
        /**
         * 使用 Apache Commons Compress 库进行Gzip解压缩
         *
         * @param inputFile  压缩文件
         * @param outputFile 解压后的文件
         * @throws IOException 解压过程中可能出现的异常
         */
        public static void gzipDecompress(File inputFile, File outputFile) throws IOException {
            // 创建输入流读取压缩文件
            try (GzipCompressorInputStream gzis = new GzipCompressorInputStream(new FileInputStream(inputFile));
                 // 创建输出流写入解压后的文件
                 FileOutputStream fos = new FileOutputStream(outputFile)) {
                // 将输入流的数据解压并写入输出流
                IOUtils.copy(gzis, fos);
            }
        }
    
        /**
         * 使用 Apache Commons Compress 库进行Tar压缩
         *
         * @param inputFiles 要压缩的文件列表
         * @param outputFile 压缩后的文件
         * @throws IOException 压缩过程中可能出现的异常
         */
        public static void tarCompress(File[] inputFiles, File outputFile) throws IOException {
            // 创建压缩输出流写入压缩后的文件
            try (TarArchiveOutputStream taros = new TarArchiveOutputStream(new FileOutputStream(outputFile))) {
                // 设置压缩格式为gzip
                taros.setLongFileMode(TarArchiveOutputStream.LONGFILE_GNU);
    
                // 遍历要压缩的文件列表
                for (File inputFile : inputFiles) {
                    // 创建压缩实体并设置文件名
                    ArchiveEntry entry = taros.createArchiveEntry(inputFile, inputFile.getName());
                    // 将实体写入压缩输出流
                    taros.putArchiveEntry(entry);
    
                    // 创建输入流读取要压缩的文件
                    try (FileInputStream fis = new FileInputStream(inputFile)) {
                        // 将输入流的数据写入压缩输出流
                        IOUtils.copy(fis, taros);
                    }
    
                    // 关闭当前压缩实体
                    taros.closeArchiveEntry();
                }
            }
        }
    
        /**
         * 使用 Apache Commons Compress 库进行Tar解压缩
         *
         * @param inputFile   压缩文件
         * @param outputDir   解压后的目录
         * @throws IOException 解压过程中可能出现的异常
         */
        public static void tarDecompress(File inputFile, File outputDir) throws IOException {
            // 创建输入流读取压缩文件
            try (TarArchiveInputStream taris = new TarArchiveInputStream(new FileInputStream(inputFile))) {
                // 遍历压缩文件中的实体
                ArchiveEntry entry;
                while ((entry = taris.getNextEntry()) != null) {
                    // 获取实体的文件名
                    String fileName = entry.getName();
                    // 创建输出文件并设置输出目录
                    File outputFile = new File(outputDir, fileName);
    
                    // 如果实体是目录,则创建相应目录;否则创建输出文件并写入数据
                    if (entry.isDirectory()) {
                        outputFile.mkdirs();
                    } else {
                        try (FileOutputStream fos = new FileOutputStream(outputFile)) {
                            // 将输入流的数据写入输出文件
                            IOUtils.copy(taris, fos);
                        }
                    }
                }
            }
        }
    
        public static void main(String[] args) {
            try {
                File inputFile = new File("input.txt");
                File gzipFile = new File("output.gz");
                File outputFile = new File("output.txt");
                File[] tarInputFiles = {new File("file1.txt"), new File("file2.txt")};
                File tarFile = new File("output.tar");
    
                // Gzip压缩
                gzipCompress(inputFile, gzipFile);
    
                // Gzip解压缩
                gzipDecompress(gzipFile, outputFile);
    
                // Tar压缩
                tarCompress(tarInputFiles, tarFile);
    
                // Tar解压缩
                tarDecompress(tarFile, new File("outputDir"));
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
  • Zip4j使用:

    import net.lingala.zip4j.ZipFile;
    import net.lingala.zip4j.exception.ZipException;
    import net.lingala.zip4j.model.ZipParameters;
    import net.lingala.zip4j.util.Zip4jConstants;
    
    import java.io.File;
    
    public class Zip4jUtil {
        public static void compress(String sourceDir, String zipFile, String password) throws ZipException {
            // 创建 ZipFile 对象,指定要生成的压缩文件
            ZipFile zip = new ZipFile(zipFile);
            
            // 设置压缩参数
            ZipParameters parameters = new ZipParameters();
            parameters.setCompressionMethod(Zip4jConstants.COMP_DEFLATE); // 设置压缩方法
            parameters.setCompressionLevel(Zip4jConstants.DEFLATE_LEVEL_NORMAL); // 设置压缩级别
            if (password != null && !password.isEmpty()) {
                parameters.setEncryptFiles(true); // 设置是否加密文件
                parameters.setEncryptionMethod(Zip4jConstants.ENC_METHOD_STANDARD); // 设置加密方法
                parameters.setPassword(password); // 设置密码
            }
            
            // 添加要压缩的文件或文件夹
            File sourceFile = new File(sourceDir);
            zip.addFolder(sourceFile, parameters);
        }
    
        public static void decompress(String zipFile, String destDir, String password) throws ZipException {
            // 创建 ZipFile 对象,指定要解压缩的文件
            ZipFile zip = new ZipFile(zipFile);
            
            // 设置解压密码(如果有)
            if (password != null && !password.isEmpty()) {
                if (zip.isEncrypted()) {
                    zip.setPassword(password);
                } else {
                    throw new ZipException("压缩文件未加密,请检查密码设置。");
                }
            }
            
            // 解压缩文件到指定目录
            zip.extractAll(destDir);
        }
    
        public static void main(String[] args) {
            try {
                String sourceDir = "source_directory";
                String zipFile = "compressed.zip";
                String destDir = "destination_directory";
                String password = "123456"; // 设置压缩密码,如果不需要加密可以设为null或空字符串
    
                // 压缩
                compress(sourceDir, zipFile, password);
    
                // 解压缩
                decompress(zipFile, destDir, password);
            } catch (ZipException e) {
                e.printStackTrace();
            }
        }
    }
  • LZ4的使用:

    import net.jpountz.lz4.*;
    
    import java.io.ByteArrayInputStream;
    import java.io.ByteArrayOutputStream;
    import java.io.IOException;
    
    public class LZ4Util {
        /**
         * 使用 LZ4 算法压缩数据
         *
         * @param data 要压缩的数据
         * @return 压缩后的数据
         * @throws IOException 压缩过程中可能出现的异常
         */
        public static byte[] compress(byte[] data) throws IOException {
            // 获取 LZ4 算法的压缩器
            LZ4Compressor compressor = LZ4Factory.fastestInstance().fastCompressor();
    
            // 计算压缩后的数据最大长度
            int maxCompressedLength = compressor.maxCompressedLength(data.length);
    
            // 创建一个缓冲区用于存储压缩后的数据
            byte[] compressedData = new byte[maxCompressedLength];
    
            // 进行压缩,并获取压缩后的数据长度
            int compressedLength = compressor.compress(data, 0, data.length, compressedData, 0);
    
            // 根据实际压缩后的数据长度,创建一个新的数组来存储压缩后的数据
            byte[] result = new byte[compressedLength];
            System.arraycopy(compressedData, 0, result, 0, compressedLength);
    
            return result;
        }
    
        /**
         * 使用 LZ4 算法解压数据
         *
         * @param compressedData 压缩后的数据
         * @param originalLength 原始数据的长度
         * @return 解压后的数据
         * @throws IOException 解压过程中可能出现的异常
         */
        public static byte[] decompress(byte[] compressedData, int originalLength) throws IOException {
            // 获取 LZ4 算法的解压缩器
            LZ4FastDecompressor decompressor = LZ4Factory.fastestInstance().fastDecompressor();
    
            // 创建一个新的数组,用于存储解压后的数据
            byte[] result = new byte[originalLength];
    
            // 进行解压缩
            decompressor.decompress(compressedData, 0, result, 0, originalLength);
    
            return result;
        }
    
        public static void main(String[] args) {
            try {
                String inputString = "Hello, LZ4 compression!";
                byte[] inputData = inputString.getBytes();
    
                // 压缩
                byte[] compressedData = compress(inputData);
    
                // 解压缩
                byte[] decompressedData = decompress(compressedData, inputData.length);
    
                System.out.println("原始数据:" + inputString);
                System.out.println("压缩后数据:" + new String(compressedData));
                System.out.println("解压缩后数据:" + new String(decompressedData));
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
  • Snappy的使用

    import org.xerial.snappy.Snappy;
    
    import java.io.IOException;
    
    public class SnappyUtil {
        /**
         * 使用 Snappy 算法压缩数据
         *
         * @param data 要压缩的数据
         * @return 压缩后的数据
         * @throws IOException 压缩过程中可能出现的异常
         */
        public static byte[] compress(byte[] data) throws IOException {
            // 调用 Snappy 的压缩方法进行数据压缩
            return Snappy.compress(data);
        }
    
        /**
         * 使用 Snappy 算法解压数据
         *
         * @param compressedData 压缩后的数据
         * @return 解压后的数据
         * @throws IOException 解压过程中可能出现的异常
         */
        public static byte[] decompress(byte[] compressedData) throws IOException {
            // 调用 Snappy 的解压方法进行数据解压缩
            return Snappy.uncompress(compressedData);
        }
    
        public static void main(String[] args) {
            try {
                String inputString = "Hello, Snappy compression!";
                byte[] inputData = inputString.getBytes();
    
                // 压缩
                byte[] compressedData = compress(inputData);
    
                // 解压缩
                byte[] decompressedData = decompress(compressedData);
    
                System.out.println("原始数据:" + inputString);
                System.out.println("压缩后数据:" + new String(compressedData));
                System.out.println("解压缩后数据:" + new String(decompressedData));
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

三、综合比较与选取

压缩算法原始数据大小压缩后数据大小解压缩次数耗时(ms)
common-compress(bzip2)3260586100002361/2852/2676/2138
gzip326059010000171/163/152/146/148
lz4326011031000061/60/62/73/63
snappy326010561000036/39/33/33/33

总结以上工具的特点如下:

  • java.util.zip:Java标准库提供的压缩与解压工具,使用简单方便,适用于基本的压缩与解压需求,但性能较其他库稍逊。
  • Apache Commons Compress:功能丰富的开源压缩库,支持多种压缩格式,包括zip、tar、gzip、bzip2等,适用于处理各种类型的压缩文件,性能较好。
  • Zip4j:基于java.util.zip的封装库,提供更便捷的API,支持密码保护和分卷压缩等功能,适用于需要额外功能的压缩需求。
  • LZ4:高压缩速度和解压速度的压缩库,适用于大规模数据压缩和快速数据传输场景,但压缩比较低。
  • Snappy:极高的压缩速度和较好的解压速度,适用于低延迟的数据传输场景,但压缩比较低。

综合选择压缩工具时,可以根据实际需求权衡性能和功能。如果需要高性能的压缩和解压速度,可以选择LZ4或Snappy;如果需要支持更多的压缩格式和功能,可以选择Apache Commons Compress或Zip4j;如果仅需简单的压缩和解压操作,可以使用java.util.zip。

注意:即便同一种压缩格式,比如zip, 也会有不同的版本,如果采用jdk或zip4j可能并不能成功解压, 如果需要更好的兼容与稳定性, 可以采用Apache Commons Compress进行解压处理。

总结

到此这篇关于Java主流压缩解压工具对比、用法与选取的文章就介绍到这了,更多相关JAVA主流压缩解压工具内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Java常用数字工具类 数字转汉字(1)

    Java常用数字工具类 数字转汉字(1)

    这篇文章主要为大家详细介绍了Java常用数字工具类,数字转汉字,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-05-05
  • Springboot实现XSS漏洞过滤的示例代码

    Springboot实现XSS漏洞过滤的示例代码

    这篇文章主要介绍了Springboot实现XSS漏洞过滤的示例代码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-01-01
  • Java异常处理之try...catch...语句的使用进阶

    Java异常处理之try...catch...语句的使用进阶

    这篇文章主要介绍了Java异常处理之try...catch...语句的使用进阶,重点在于牵扯相关IO使用时的资源调配情况,需要的朋友可以参考下
    2015-11-11
  • java日期时间操作工具类

    java日期时间操作工具类

    这篇文章主要为大家详细介绍了java日期时间操作工具类,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-12-12
  • SWT(JFace)体验之Sash(活动控件)

    SWT(JFace)体验之Sash(活动控件)

    SWT(JFace)体验之Sash(活动控件)
    2009-06-06
  • java编程实现获取服务器IP地址及MAC地址的方法

    java编程实现获取服务器IP地址及MAC地址的方法

    这篇文章主要介绍了java编程实现获取机器IP地址及MAC地址的方法,实例分析了Java分别针对单网卡及多网卡的情况下获取服务器IP地址与MAC地址的相关技巧,需要的朋友可以参考下
    2015-11-11
  • Java项目如何防止SQL注入(多种方案汇总)

    Java项目如何防止SQL注入(多种方案汇总)

    SQL注入即是指web应用程序对用户输入数据的合法性没有判断或过滤不严,攻击者可以在web应用程序中事先定义好的查询语句的结尾上添加额外的SQL语句,这篇文章主要介绍了 Java项目防止SQL注入的四种方案,需要的朋友可以参考下
    2023-12-12
  • Dubbo新版本zk注册中心连接问题及解决

    Dubbo新版本zk注册中心连接问题及解决

    这篇文章主要介绍了Dubbo新版本zk注册中心连接问题及解决,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-05-05
  • Java_Spring之XML 的 AOP 配置

    Java_Spring之XML 的 AOP 配置

    这篇文章主要介绍了Java_Spring中基于XML的AOP配置,上篇讲到的是基于注解的AOP配置,对XML感兴趣的同学可以参考阅读本文
    2023-04-04
  • Java中i++与++i的区别和使用

    Java中i++与++i的区别和使用

    这篇文章主要介绍了Java中i++与++i的区别和使用,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-02-02

最新评论