Java中的压缩和解压缩技术是指通过特定算法将数据体积减小(压缩)或恢复原始大小(解压缩)的过程,常用于文件存储优化、网络传输加速等场景。Java提供了多种API支持不同压缩格式,以下是核心技术和使用方法:

1. 核心压缩API与格式

Java标准库提供了以下核心类和接口:

格式 核心类 描述
ZIP java.util.zip包:
ZipOutputStream
ZipInputStream
ZipEntry
最常用的归档格式,支持多文件压缩,带目录结构。
GZIP java.util.zip包:
GZIPOutputStream
GZIPInputStream
用于单文件压缩,适合文本类数据(如日志、HTML)。
JAR java.util.jar包:
JarOutputStream
JarInputStream
基于ZIP的Java归档格式,支持Manifest文件。
Deflater/Inflater java.util.zip包:
Deflater
Inflater
底层压缩算法(DEFLATE),可自定义压缩级别。

2. 使用ZIP格式压缩/解压缩多文件

压缩文件

将多个文件打包为ZIP:

import java.io.*;
import java.util.zip.*;

public class ZipExample {
    public static void main(String[] args) {
        String[] filesToZip = {"file1.txt", "file2.txt"};
        String zipFilePath = "archive.zip";

        try (ZipOutputStream zipOut = new ZipOutputStream(new FileOutputStream(zipFilePath))) {
            for (String filePath : filesToZip) {
                File file = new File(filePath);
                if (file.exists()) {
                    // 创建ZIP条目并添加到ZIP流
                    ZipEntry zipEntry = new ZipEntry(file.getName());
                    zipOut.putNextEntry(zipEntry);

                    // 读取文件内容并写入ZIP流
                    try (FileInputStream fis = new FileInputStream(file)) {
                        byte[] buffer = new byte[1024];
                        int length;
                        while ((length = fis.read(buffer)) > 0) {
                            zipOut.write(buffer, 0, length);
                        }
                    }
                    zipOut.closeEntry();
                }
            }
            System.out.println("ZIP压缩完成:" + zipFilePath);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

解压缩文件

从ZIP文件中提取所有文件:

import java.io.*;
import java.util.zip.*;

public class UnzipExample {
    public static void main(String[] args) {
        String zipFilePath = "archive.zip";
        String destDirectory = "extracted";

        try (ZipInputStream zipIn = new ZipInputStream(new FileInputStream(zipFilePath))) {
            ZipEntry entry = zipIn.getNextEntry();
            while (entry != null) {
                String filePath = destDirectory + File.separator + entry.getName();
                if (!entry.isDirectory()) {
                    // 创建文件并写入解压内容
                    extractFile(zipIn, filePath);
                } else {
                    // 创建目录
                    File dir = new File(filePath);
                    dir.mkdirs();
                }
                zipIn.closeEntry();
                entry = zipIn.getNextEntry();
            }
            System.out.println("ZIP解压缩完成到:" + destDirectory);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private static void extractFile(ZipInputStream zipIn, String filePath) throws IOException {
        try (BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(filePath))) {
            byte[] bytesIn = new byte[1024];
            int read;
            while ((read = zipIn.read(bytesIn)) != -1) {
                bos.write(bytesIn, 0, read);
            }
        }
    }
}

3. 使用GZIP压缩/解压缩单文件

GZIP适用于单个文件(如文本、JSON)的压缩:

import java.io.*;
import java.util.zip.*;

public class GzipExample {
    public static void main(String[] args) {
        String sourceFile = "large_text.txt";
        String compressedFile = "large_text.txt.gz";

        // 压缩文件
        try (FileInputStream fis = new FileInputStream(sourceFile);
             GZIPOutputStream gzos = new GZIPOutputStream(new FileOutputStream(compressedFile))) {
            
            byte[] buffer = new byte[1024];
            int bytesRead;
            while ((bytesRead = fis.read(buffer)) != -1) {
                gzos.write(buffer, 0, bytesRead);
            }
            System.out.println("GZIP压缩完成:" + compressedFile);
        } catch (IOException e) {
            e.printStackTrace();
        }

        // 解压缩文件
        String decompressedFile = "large_text_decompressed.txt";
        try (GZIPInputStream gzis = new GZIPInputStream(new FileInputStream(compressedFile));
             FileOutputStream fos = new FileOutputStream(decompressedFile)) {
            
            byte[] buffer = new byte[1024];
            int bytesRead;
            while ((bytesRead = gzis.read(buffer)) != -1) {
                fos.write(buffer, 0, bytesRead);
            }
            System.out.println("GZIP解压缩完成:" + decompressedFile);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

4. 自定义压缩级别与性能优化

通过Deflater设置压缩级别(0-9,默认为6):

// 创建ZIP输出流时指定压缩级别
ZipOutputStream zipOut = new ZipOutputStream(new FileOutputStream("custom.zip"));
zipOut.setLevel(Deflater.BEST_COMPRESSION);  // 最高压缩比(速度慢)
// 或使用 Deflater.DEFAULT_COMPRESSION(平衡)、Deflater.BEST_SPEED(速度快)

5. 处理特殊场景

递归压缩目录

压缩整个目录及其子目录:

private static void zipDirectory(File dir, String parentPath, ZipOutputStream zipOut) throws IOException {
    for (File file : dir.listFiles()) {
        if (file.isDirectory()) {
            zipDirectory(file, parentPath + file.getName() + "/", zipOut);
        } else {
            ZipEntry entry = new ZipEntry(parentPath + file.getName());
            zipOut.putNextEntry(entry);
            try (FileInputStream fis = new FileInputStream(file)) {
                byte[] buffer = new byte[1024];
                int length;
                while ((length = fis.read(buffer)) > 0) {
                    zipOut.write(buffer, 0, length);
                }
            }
            zipOut.closeEntry();
        }
    }
}

使用JAR格式

JAR是ZIP的扩展,支持Java特定的Manifest文件:

import java.util.jar.*;

// 创建JAR文件
try (JarOutputStream jos = new JarOutputStream(new FileOutputStream("myapp.jar"))) {
    // 添加Manifest文件
    Manifest manifest = new Manifest();
    manifest.getMainAttributes().put(Attributes.Name.MANIFEST_VERSION, "1.0");
    jos.putNextEntry(new JarEntry("META-INF/MANIFEST.MF"));
    manifest.write(jos);
    jos.closeEntry();

    // 添加其他文件...
} catch (IOException e) {
    e.printStackTrace();
}

6. 第三方库推荐

对于更复杂的场景(如7-Zip、BZip2、LZMA),可使用以下第三方库:

  • Apache Commons Compress:支持更多压缩格式(如7z、ARJ、CPIO)。
  • XZ for Java:提供LZMA2压缩算法支持。
  • JZlib:优化的DEFLATE实现,性能优于标准库。

总结

需求 推荐API 示例
压缩多文件 ZipOutputStream zipOut.putNextEntry(new ZipEntry("file.txt"))
压缩单文件 GZIPOutputStream gzos.write(data, 0, length)
自定义压缩级别 Deflater zipOut.setLevel(Deflater.BEST_SPEED)
处理JAR文件 JarOutputStream jos.putNextEntry(new JarEntry("META-INF/MANIFEST.MF"))

合理选择压缩格式和API,可高效处理Java中的文件压缩与解压缩需求。