上一篇
文件压缩java怎么写
- 后端开发
- 2025-07-19
- 3269
使用ZipOutputStream创建压缩流,遍历文件并写入压缩包,设置缓冲区,关闭
在Java中实现文件压缩主要依赖java.util.zip包或第三方库(如Apache Commons Compress),以下是详细的实现步骤、代码示例及注意事项,涵盖ZIP和GZIP两种常见压缩格式。
Java文件压缩基础
-
核心类库
ZipOutputStream/ZipInputStream:用于ZIP格式压缩与解压。GZIPOutputStream/GZIPInputStream:用于GZIP格式压缩与解压。FileInputStream/FileOutputStream:读写文件数据。BufferedInputStream/BufferedOutputStream:提升读写效率。
-
压缩原理
- ZIP支持多文件压缩,可保留目录结构;GZIP通常用于单文件压缩。
- 压缩级别范围为0(无压缩)到9(最大压缩),需平衡压缩率与性能。
ZIP格式压缩实现
压缩单个文件
import java.io.;
import java.util.zip.;
public class FileCompressor {
public static void zipSingleFile(String srcFile, String zipFile) throws IOException {
try (FileOutputStream fos = new FileOutputStream(zipFile);
ZipOutputStream zos = new ZipOutputStream(fos);
FileInputStream fis = new FileInputStream(srcFile)) {
ZipEntry entry = new ZipEntry(new File(srcFile).getName());
zos.putNextEntry(entry);
byte[] buffer = new byte[4096];
int len;
while ((len = fis.read(buffer)) > 0) {
zos.write(buffer, 0, len);
}
}
}
}
关键点:

- 使用
ZipEntry指定压缩文件的名称。 - 通过缓冲区(
byte[] buffer)提高读写效率。
压缩多个文件或目录
public static void zipDirectory(String srcDir, String zipFile) throws IOException {
try (FileOutputStream fos = new FileOutputStream(zipFile);
ZipOutputStream zos = new ZipOutputStream(fos)) {
File file = new File(srcDir);
compressFile(file, zos, "");
}
}
private static void compressFile(File file, ZipOutputStream zos, String parentPath) throws IOException {
if (file.isDirectory()) {
// 空目录需创建ZipEntry以保留结构
zos.putNextEntry(new ZipEntry(parentPath + "/"));
zos.closeEntry();
for (File child : file.listFiles()) {
compressFile(child, zos, parentPath + "/" + file.getName());
}
} else {
try (FileInputStream fis = new FileInputStream(file)) {
ZipEntry entry = new ZipEntry(parentPath + "/" + file.getName());
zos.putNextEntry(entry);
byte[] buffer = new byte[4096];
int len;
while ((len = fis.read(buffer)) > 0) {
zos.write(buffer, 0, len);
}
}
}
}
关键点:
- 递归遍历目录,对空目录创建
ZipEntry以保留层级结构。 - 通过
parentPath参数维护相对路径,避免绝对路径导致压缩包移植性差。
设置压缩级别与性能优化
zos.setLevel(Deflater.BEST_COMPRESSION); // 设置最高压缩级别
性能优化策略:
| 优化方向 | 具体措施 |
|———-|———-|
| 缓冲区大小 | 使用byte[] buffer(建议4KB或更大)减少I/O次数 |
| 多线程压缩 | 对独立文件分配线程并行压缩,但需避免共享ZipOutputStream |
| 大文件分块 | 分段读取文件,避免内存溢出 |
GZIP格式压缩
GZIP适用于单文件压缩,不支持目录结构。

public static void gzipFile(String srcFile, String gzipFile) throws IOException {
try (FileInputStream fis = new FileInputStream(srcFile);
FileOutputStream fos = new FileOutputStream(gzipFile);
GZIPOutputStream gos = new GZIPOutputStream(fos)) {
byte[] buffer = new byte[4096];
int len;
while ((len = fis.read(buffer)) > 0) {
gos.write(buffer, 0, len);
}
}
}
关键点:
- GZIP自动处理压缩级别(默认中等),可通过
GZIPOutputStream(fos, Deflater.BEST_COMPRESSION)自定义。
解压操作
解压ZIP文件
public static void unzipFile(String zipFile, String destDir) throws IOException {
try (FileInputStream fis = new FileInputStream(zipFile);
ZipInputStream zis = new ZipInputStream(fis)) {
ZipEntry entry;
while ((entry = zis.getNextEntry()) != null) {
File file = new File(destDir, entry.getName());
if (entry.isDirectory()) {
file.mkdirs();
} else {
file.getParentFile().mkdirs();
try (FileOutputStream fos = new FileOutputStream(file)) {
byte[] buffer = new byte[4096];
int len;
while ((len = zis.read(buffer)) > 0) {
fos.write(buffer, 0, len);
}
}
}
zis.closeEntry();
}
}
}
注意事项:
- 防止ZIP Slip破绽(反面路径穿透),需验证
entry.getName()不包含等非规字符。
解压GZIP文件
public static void gunzipFile(String gzipFile, String outputFile) throws IOException {
try (FileInputStream fis = new FileInputStream(gzipFile);
GZIPInputStream gis = new GZIPInputStream(fis);
FileOutputStream fos = new FileOutputStream(outputFile)) {
byte[] buffer = new byte[4096];
int len;
while ((len = gis.read(buffer)) > 0) {
fos.write(buffer, 0, len);
}
}
}
常见问题与解决方案
FAQs
Q1:如何设置压缩级别?
A1:通过ZipOutputStream.setLevel(int level)或GZIPOutputStream(OutputStream, int level)设置,值范围为0(无压缩)到9(最大压缩)。

Q2:中文文件名出现乱码如何解决?
A2:使用Apache Commons Compress库,并指定UTF-8编码:
ZipArchiveEntry entry = new ZipArchiveEntry(file.getName()); entry.setUnicodeExtra(true); // 启用UTF-8支持
或手动设置ZipEntry的注释字段存储原始文件名。
- ZIP适合多文件压缩,保留目录结构;GZIP适合单文件压缩。
- 性能优化需关注缓冲区、多线程及压缩级别。
- 第三方库(如Apache Commons Compress)可解决编码、格式兼容等问题
