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中的文件压缩与解压缩需求。