文件压缩java怎么写

使用ZipOutputStream创建压缩流,遍历文件并写入压缩包,设置缓冲区,关闭

在Java中实现文件压缩主要依赖java.util.zip包或第三方库(如Apache Commons Compress),以下是详细的实现步骤、代码示例及注意事项,涵盖ZIP和GZIP两种常见压缩格式。

文件压缩java怎么写

Java文件压缩基础

  1. 核心类库

    • ZipOutputStream/ZipInputStream:用于ZIP格式压缩与解压。
    • GZIPOutputStream/GZIPInputStream:用于GZIP格式压缩与解压。
    • FileInputStream/FileOutputStream:读写文件数据。
    • BufferedInputStream/BufferedOutputStream:提升读写效率。
  2. 压缩原理

    • 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);
            }
        }
    }
}

关键点

文件压缩java怎么写

  • 递归遍历目录,对空目录创建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();
        }
    }
}

注意事项

文件压缩java怎么写

  • 防止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)可解决编码、格式兼容等问题

原创文章,发布者:酷盾叔,转转请注明出处:https://www.kd.cn/ask/68631.html

(0)
酷盾叔的头像酷盾叔
上一篇 2025年7月19日 07:36
下一篇 2025年7月19日 07:40

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

联系我们

400-880-8834

在线咨询: QQ交谈

邮件:HI@E.KD.CN