Java主流壓縮解壓工具對比、用法與選取詳解
一、JAVA主流壓縮工具
java.util.zip:
**說明:**Java標準庫提供的壓縮與解壓功能,包含在
java.util.zip
包中。通過ZipInputStream
和ZipOutputStream
可以實現(xiàn)ZIP格式的壓縮與解壓縮操作。適用場景: 適合簡單的ZIP格式壓縮與解壓縮操作,可用于對單個文件或目錄進行壓縮和解壓縮。
Apache Commons Compress:
**說明:**Apache Commons Compress是Apache軟件基金會提供的開源壓縮與解壓工具包,支持多種壓縮格式,包括ZIP、Gzip、Tar等。通過該工具包,可以進行更復(fù)雜的壓縮與解壓縮操作。
**適用場景:**支持多種壓縮格式,如ZIP、Gzip、Tar等,適合復(fù)雜的壓縮與解壓縮操作,可用于處理各種壓縮格式和對多個文件或目錄進行打包、解壓縮。
Java Zip4j:
**說明:**Zip4j是一個開源的Java庫,提供了對ZIP格式的支持,并且支持密碼保護、分卷壓縮等功能。
**適用場景:**支持ZIP格式,提供了一些高級功能,如密碼保護、分卷壓縮等,適合復(fù)雜的ZIP格式的壓縮與解壓縮操作。
LZ4:
**說明:**LZ4是一種高性能的壓縮算法,具有快速的壓縮和解壓縮速度,但壓縮比相對較低。
**適用場景:**適合對大量數(shù)據(jù)進行實時壓縮和解壓縮,例如在網(wǎng)絡(luò)傳輸或大數(shù)據(jù)處理中,追求較高的壓縮/解壓縮速度。
Snappy
**說明:**Snappy是一種快速的壓縮和解壓縮算法,具有較快的壓縮和解壓縮速度,適合高性能場景。
**適用場景:**適用于對大規(guī)模數(shù)據(jù)進行實時壓縮和解壓縮,例如在大數(shù)據(jù)處理和分析中。
這些壓縮與解壓工具可以根據(jù)項目的需求和使用場景選擇合適的工具進行壓縮與解壓縮操作。Java標準庫的java.util.zip
包通常適用于簡單的ZIP格式壓縮與解壓縮,Apache Commons Compress和Java Zip4j提供了更多的壓縮格式和功能選項。對于大型數(shù)據(jù)集和高性能要求的場景,還可以考慮使用專門的壓縮工具或算法,如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 壓縮過程中可能出現(xiàn)的異常 */ public static void zipCompress(File inputFile, File outputFile) throws IOException { // 創(chuàng)建輸出流寫入壓縮后的文件 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 壓縮過程中可能出現(xiàn)的異常 */ 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 壓縮過程中可能出現(xiàn)的異常 */ private static void zipFile(File file, ZipOutputStream zos, String entry) throws IOException { // 創(chuàng)建壓縮實體并設(shè)置實體名稱 ZipEntry zipEntry = new ZipEntry(entry); // 將壓縮實體寫入壓縮輸出流 zos.putNextEntry(zipEntry); // 創(chuàng)建輸入流讀取文件內(nèi)容,并將內(nèi)容寫入壓縮輸出流 try (FileInputStream fis = new FileInputStream(file)) { byte[] buffer = new byte[1024]; int length; while ((length = fis.read(buffer)) > 0) { zos.write(buffer, 0, length); } } // 關(guān)閉當前壓縮實體 zos.closeEntry(); } /** * 使用java.util.zip庫進行文件解壓縮 * * @param inputFile 壓縮文件 * @param outputDir 解壓后的目錄 * @throws IOException 解壓過程中可能出現(xiàn)的異常 */ public static void zipDecompress(File inputFile, File outputDir) throws IOException { // 創(chuàng)建輸入流讀取壓縮文件 try (ZipInputStream zis = new ZipInputStream(new FileInputStream(inputFile))) { // 遍歷壓縮文件中的實體 ZipEntry zipEntry; while ((zipEntry = zis.getNextEntry()) != null) { // 獲取實體的名稱 String entryName = zipEntry.getName(); // 創(chuàng)建輸出文件并設(shè)置輸出目錄 File outputFile = new File(outputDir, entryName); // 如果實體是目錄,則創(chuàng)建相應(yīng)目錄;否則創(chuàng)建輸出文件并寫入數(shù)據(jù) if (zipEntry.isDirectory()) { outputFile.mkdirs(); } else { try (FileOutputStream fos = new FileOutputStream(outputFile)) { // 將輸入流的數(shù)據(jù)寫入輸出文件 byte[] buffer = new byte[1024]; int length; while ((length = zis.read(buffer)) > 0) { fos.write(buffer, 0, length); } } } // 關(guān)閉當前解壓實體 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 壓縮過程中可能出現(xiàn)的異常 */ public static void gzipCompress(File inputFile, File outputFile) throws IOException { // 創(chuàng)建輸入流讀取要壓縮的文件 try (FileInputStream fis = new FileInputStream(inputFile); // 創(chuàng)建壓縮輸出流寫入壓縮后的文件 GzipCompressorOutputStream gzos = new GzipCompressorOutputStream(new FileOutputStream(outputFile))) { // 將輸入流的數(shù)據(jù)壓縮并寫入輸出流 IOUtils.copy(fis, gzos); } } /** * 使用 Apache Commons Compress 庫進行Gzip解壓縮 * * @param inputFile 壓縮文件 * @param outputFile 解壓后的文件 * @throws IOException 解壓過程中可能出現(xiàn)的異常 */ public static void gzipDecompress(File inputFile, File outputFile) throws IOException { // 創(chuàng)建輸入流讀取壓縮文件 try (GzipCompressorInputStream gzis = new GzipCompressorInputStream(new FileInputStream(inputFile)); // 創(chuàng)建輸出流寫入解壓后的文件 FileOutputStream fos = new FileOutputStream(outputFile)) { // 將輸入流的數(shù)據(jù)解壓并寫入輸出流 IOUtils.copy(gzis, fos); } } /** * 使用 Apache Commons Compress 庫進行Tar壓縮 * * @param inputFiles 要壓縮的文件列表 * @param outputFile 壓縮后的文件 * @throws IOException 壓縮過程中可能出現(xiàn)的異常 */ public static void tarCompress(File[] inputFiles, File outputFile) throws IOException { // 創(chuàng)建壓縮輸出流寫入壓縮后的文件 try (TarArchiveOutputStream taros = new TarArchiveOutputStream(new FileOutputStream(outputFile))) { // 設(shè)置壓縮格式為gzip taros.setLongFileMode(TarArchiveOutputStream.LONGFILE_GNU); // 遍歷要壓縮的文件列表 for (File inputFile : inputFiles) { // 創(chuàng)建壓縮實體并設(shè)置文件名 ArchiveEntry entry = taros.createArchiveEntry(inputFile, inputFile.getName()); // 將實體寫入壓縮輸出流 taros.putArchiveEntry(entry); // 創(chuàng)建輸入流讀取要壓縮的文件 try (FileInputStream fis = new FileInputStream(inputFile)) { // 將輸入流的數(shù)據(jù)寫入壓縮輸出流 IOUtils.copy(fis, taros); } // 關(guān)閉當前壓縮實體 taros.closeArchiveEntry(); } } } /** * 使用 Apache Commons Compress 庫進行Tar解壓縮 * * @param inputFile 壓縮文件 * @param outputDir 解壓后的目錄 * @throws IOException 解壓過程中可能出現(xiàn)的異常 */ public static void tarDecompress(File inputFile, File outputDir) throws IOException { // 創(chuàng)建輸入流讀取壓縮文件 try (TarArchiveInputStream taris = new TarArchiveInputStream(new FileInputStream(inputFile))) { // 遍歷壓縮文件中的實體 ArchiveEntry entry; while ((entry = taris.getNextEntry()) != null) { // 獲取實體的文件名 String fileName = entry.getName(); // 創(chuàng)建輸出文件并設(shè)置輸出目錄 File outputFile = new File(outputDir, fileName); // 如果實體是目錄,則創(chuàng)建相應(yīng)目錄;否則創(chuàng)建輸出文件并寫入數(shù)據(jù) if (entry.isDirectory()) { outputFile.mkdirs(); } else { try (FileOutputStream fos = new FileOutputStream(outputFile)) { // 將輸入流的數(shù)據(jù)寫入輸出文件 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 { // 創(chuàng)建 ZipFile 對象,指定要生成的壓縮文件 ZipFile zip = new ZipFile(zipFile); // 設(shè)置壓縮參數(shù) ZipParameters parameters = new ZipParameters(); parameters.setCompressionMethod(Zip4jConstants.COMP_DEFLATE); // 設(shè)置壓縮方法 parameters.setCompressionLevel(Zip4jConstants.DEFLATE_LEVEL_NORMAL); // 設(shè)置壓縮級別 if (password != null && !password.isEmpty()) { parameters.setEncryptFiles(true); // 設(shè)置是否加密文件 parameters.setEncryptionMethod(Zip4jConstants.ENC_METHOD_STANDARD); // 設(shè)置加密方法 parameters.setPassword(password); // 設(shè)置密碼 } // 添加要壓縮的文件或文件夾 File sourceFile = new File(sourceDir); zip.addFolder(sourceFile, parameters); } public static void decompress(String zipFile, String destDir, String password) throws ZipException { // 創(chuàng)建 ZipFile 對象,指定要解壓縮的文件 ZipFile zip = new ZipFile(zipFile); // 設(shè)置解壓密碼(如果有) if (password != null && !password.isEmpty()) { if (zip.isEncrypted()) { zip.setPassword(password); } else { throw new ZipException("壓縮文件未加密,請檢查密碼設(shè)置。"); } } // 解壓縮文件到指定目錄 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"; // 設(shè)置壓縮密碼,如果不需要加密可以設(shè)為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 算法壓縮數(shù)據(jù) * * @param data 要壓縮的數(shù)據(jù) * @return 壓縮后的數(shù)據(jù) * @throws IOException 壓縮過程中可能出現(xiàn)的異常 */ public static byte[] compress(byte[] data) throws IOException { // 獲取 LZ4 算法的壓縮器 LZ4Compressor compressor = LZ4Factory.fastestInstance().fastCompressor(); // 計算壓縮后的數(shù)據(jù)最大長度 int maxCompressedLength = compressor.maxCompressedLength(data.length); // 創(chuàng)建一個緩沖區(qū)用于存儲壓縮后的數(shù)據(jù) byte[] compressedData = new byte[maxCompressedLength]; // 進行壓縮,并獲取壓縮后的數(shù)據(jù)長度 int compressedLength = compressor.compress(data, 0, data.length, compressedData, 0); // 根據(jù)實際壓縮后的數(shù)據(jù)長度,創(chuàng)建一個新的數(shù)組來存儲壓縮后的數(shù)據(jù) byte[] result = new byte[compressedLength]; System.arraycopy(compressedData, 0, result, 0, compressedLength); return result; } /** * 使用 LZ4 算法解壓數(shù)據(jù) * * @param compressedData 壓縮后的數(shù)據(jù) * @param originalLength 原始數(shù)據(jù)的長度 * @return 解壓后的數(shù)據(jù) * @throws IOException 解壓過程中可能出現(xiàn)的異常 */ public static byte[] decompress(byte[] compressedData, int originalLength) throws IOException { // 獲取 LZ4 算法的解壓縮器 LZ4FastDecompressor decompressor = LZ4Factory.fastestInstance().fastDecompressor(); // 創(chuàng)建一個新的數(shù)組,用于存儲解壓后的數(shù)據(jù) 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("原始數(shù)據(jù):" + inputString); System.out.println("壓縮后數(shù)據(jù):" + new String(compressedData)); System.out.println("解壓縮后數(shù)據(jù):" + new String(decompressedData)); } catch (IOException e) { e.printStackTrace(); } } }
Snappy的使用
import org.xerial.snappy.Snappy; import java.io.IOException; public class SnappyUtil { /** * 使用 Snappy 算法壓縮數(shù)據(jù) * * @param data 要壓縮的數(shù)據(jù) * @return 壓縮后的數(shù)據(jù) * @throws IOException 壓縮過程中可能出現(xiàn)的異常 */ public static byte[] compress(byte[] data) throws IOException { // 調(diào)用 Snappy 的壓縮方法進行數(shù)據(jù)壓縮 return Snappy.compress(data); } /** * 使用 Snappy 算法解壓數(shù)據(jù) * * @param compressedData 壓縮后的數(shù)據(jù) * @return 解壓后的數(shù)據(jù) * @throws IOException 解壓過程中可能出現(xiàn)的異常 */ public static byte[] decompress(byte[] compressedData) throws IOException { // 調(diào)用 Snappy 的解壓方法進行數(shù)據(jù)解壓縮 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("原始數(shù)據(jù):" + inputString); System.out.println("壓縮后數(shù)據(jù):" + new String(compressedData)); System.out.println("解壓縮后數(shù)據(jù):" + new String(decompressedData)); } catch (IOException e) { e.printStackTrace(); } } }
三、綜合比較與選取
壓縮算法 | 原始數(shù)據(jù)大小 | 壓縮后數(shù)據(jù)大小 | 解壓縮次數(shù) | 耗時(ms) |
---|---|---|---|---|
common-compress(bzip2) | 3260 | 586 | 10000 | 2361/2852/2676/2138 |
gzip | 3260 | 590 | 10000 | 171/163/152/146/148 |
lz4 | 3260 | 1103 | 10000 | 61/60/62/73/63 |
snappy | 3260 | 1056 | 10000 | 36/39/33/33/33 |
總結(jié)以上工具的特點如下:
- java.util.zip:Java標準庫提供的壓縮與解壓工具,使用簡單方便,適用于基本的壓縮與解壓需求,但性能較其他庫稍遜。
- Apache Commons Compress:功能豐富的開源壓縮庫,支持多種壓縮格式,包括zip、tar、gzip、bzip2等,適用于處理各種類型的壓縮文件,性能較好。
- Zip4j:基于java.util.zip的封裝庫,提供更便捷的API,支持密碼保護和分卷壓縮等功能,適用于需要額外功能的壓縮需求。
- LZ4:高壓縮速度和解壓速度的壓縮庫,適用于大規(guī)模數(shù)據(jù)壓縮和快速數(shù)據(jù)傳輸場景,但壓縮比較低。
- Snappy:極高的壓縮速度和較好的解壓速度,適用于低延遲的數(shù)據(jù)傳輸場景,但壓縮比較低。
綜合選擇壓縮工具時,可以根據(jù)實際需求權(quán)衡性能和功能。如果需要高性能的壓縮和解壓速度,可以選擇LZ4或Snappy;如果需要支持更多的壓縮格式和功能,可以選擇Apache Commons Compress或Zip4j;如果僅需簡單的壓縮和解壓操作,可以使用java.util.zip。
注意:即便同一種壓縮格式,比如zip, 也會有不同的版本,如果采用jdk或zip4j可能并不能成功解壓, 如果需要更好的兼容與穩(wěn)定性, 可以采用Apache Commons Compress進行解壓處理。
總結(jié)
到此這篇關(guān)于Java主流壓縮解壓工具對比、用法與選取的文章就介紹到這了,更多相關(guān)JAVA主流壓縮解壓工具內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Java Spring使用hutool的HttpRequest發(fā)送請求的幾種方式
文章介紹了Hutool庫中用于發(fā)送HTTP請求的工具,包括添加依賴、發(fā)送GET和POST請求的方法,以及GET請求的不同參數(shù)傳遞方式,感興趣的朋友跟隨小編一起看看吧2024-11-11一文搞懂Java常見的三種代理模式(靜態(tài)代理、動態(tài)代理和cglib代理)
Java中常見的三種代理模式是靜態(tài)代理模式、動態(tài)代理模式和CGLIB代理模式,本文就來給大家詳細的講解一下這三種代理模式,感興趣的小伙伴跟著小編一起來看看吧2023-08-08Spring?Boot解決循環(huán)依賴的過程詳細記錄
這篇文章主要介紹了Spring?Boot解決循環(huán)依賴的過程,Spring框架通過三級緩存機制解決循環(huán)依賴問題,分別為singletonObjects、earlySingletonObjects和singletonFactories,需要的朋友可以參考下2024-09-09