Java原生Zip压缩/解压缩工具类

9 篇文章 0 订阅
1 篇文章 0 订阅

转载原文:
写了一个系列,写的很好,强烈推荐去看!

Java压缩技术(二) ZIP压缩——Java原生实现
Java压缩技术(三) ZIP解压缩——Java原生实现


Zip压缩/解压缩工具类

缺点:

  1. 压缩包内中文文件名会乱码;
  2. 压缩/解压缩不支持设置密码;
  3. 修改缓存系数线程不安全(不让改缓存系数就安全了);

代码:

package repalce.your.package;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.zip.CRC32;
import java.util.zip.CheckedInputStream;
import java.util.zip.CheckedOutputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;

/**
 * Zip压缩工具类(修改缓存系数线程不安全)
 */
public class ZipUtil {

    /** 文件拓展名 */
    public static final String EXT = ".zip";
    /** 缓存大小 */
    public static final int BUFFER_SIZE = 1024;
    /** 缓存系数 */
    private static int bufferCoefficient = 8;

    /**
     * 获取缓存系数
     * @return 缓存系数
     */
    public static int setBufferCoefficient(){
        return bufferCoefficient;
    }

    /**
     * 设置缓存系数
     * @param bufferCoefficient 缓存系数(大于等于1)
     */
    public static void setBufferCoefficient(int bufferCoefficient) {
        if(bufferCoefficient < 1) {
            ZipUtil.bufferCoefficient = 1;
        }else{
            ZipUtil.bufferCoefficient = bufferCoefficient;
        }
    }

    // --压缩--------------------------------------------------------------------

    /**
     * 压缩
     * @param srcPath 待压缩文件路径
     * @throws IOException IO异常
     */
    public static void compress(String srcPath) throws IOException  {
        compress(new File(srcPath));
    }

    /**
     * 压缩
     * @param srcFile 待压缩文件
     * @throws IOException IO异常
     */
    public static void compress(File srcFile) throws IOException  {
        // 检查待压缩文件是否为目录
        if(srcFile.isDirectory()) {
            compress(srcFile, srcFile.getParent() + File.separator + srcFile.getName() + EXT);
        }else{
            // 拓展名起始下标
            int extStartIndex = srcFile.getName().lastIndexOf(".");
            // 获取待压缩文件名称
            String srcFileName = srcFile.getName().substring(0, extStartIndex == -1 ? srcFile.getName().length() : extStartIndex);
            // 压缩
            compress(srcFile, srcFile.getParent() + File.separator + srcFileName + EXT);
        }
    }

    /**
     * 压缩
     * @param srcPath  待压缩文件路径
     * @param destPath 压缩文件路径
     * @throws IOException IO异常
     */
    public static void compress(String srcPath, String destPath) throws IOException {
        compress(new File(srcPath), destPath);
    }

    /**
     * 压缩
     * @param srcFile  待压缩文件
     * @param destPath 压缩文件路径
     * @throws IOException IO异常
     */
    public static void compress(File srcFile, String destPath) throws IOException  {
        compress(srcFile, new File(destPath));
    }

    /**
     * 压缩
     * @param srcPath  待压缩文件路径
     * @param destFile 压缩文件
     * @throws IOException IO异常
     */
    public static void compress(String srcPath, File destFile) throws IOException  {
        compress(new File(srcPath), destFile);
    }

    /**
     * 压缩
     * @param srcFile  待压缩文件
     * @param destFile 压缩文件
     * @throws IOException IO异常
     */
    public static void compress(File srcFile, File destFile) throws IOException  {
        CheckedOutputStream cos = new CheckedOutputStream(new FileOutputStream(destFile), new CRC32());
        ZipOutputStream zos = new ZipOutputStream(cos);

        compress(srcFile, zos, "");

        zos.flush();
        zos.close();
    }

    /**
     * 压缩
     * @param srcFile 源路径
     * @param zos     Zip输出流
     * @param path    压缩包内相对路径
     * @throws IOException IO异常
     */
    private static void compress(File srcFile, ZipOutputStream zos, String path) throws IOException  {
        // 检查待压缩文件是否为目录
        if (srcFile.isDirectory()) {
            compressDir(srcFile, zos, path);
        } else {
            compressFile(srcFile, zos, path);
        }
    }

    /**
     * 压缩目录
     * @param dir  目录文件
     * @param zos  Zip输出流
     * @param path 压缩包内相对路径
     * @throws IOException IO异常
     */
    private static void compressDir(File dir, ZipOutputStream zos, String path) throws IOException  {
        // 目录下所有文件
        File[] files = dir.listFiles();

        // 构建空目录
        if (files.length < 1) {
            ZipEntry entry = new ZipEntry(path + dir.getName() + File.separator);
            zos.putNextEntry(entry);
            zos.closeEntry();
        }

        // 递归压缩
        for (File file : files) {
            compress(file, zos, path + dir.getName() + File.separator);
        }
    }

    /**
     * 压缩文件
     * @param file 待压缩文件
     * @param zos  Zip输出流
     * @param path 压缩文件中的当前路径
     * @throws IOException IO异常
     */
    private static void compressFile(File file, ZipOutputStream zos, String path) throws IOException {
        BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file));

        ZipEntry entry = new ZipEntry(path + file.getName());
        zos.putNextEntry(entry);

        int count;
        byte data[] = new byte[BUFFER_SIZE * bufferCoefficient];
        while ((count = bis.read(data, 0, BUFFER_SIZE * bufferCoefficient)) != -1) {
            zos.write(data, 0, count);
        }

        bis.close();
        zos.closeEntry();
    }

    // --解压--------------------------------------------------------------------

    /**
     * 解压缩
     * 
     * @param srcPath 待解压文件路径
     * @throws IOException IO异常
     */
    public static void decompress(String srcPath) throws IOException {
        decompress(new File(srcPath));
    }

    /**
     * 解压缩
     * 
     * @param srcFile 待解压文件
     * @throws IOException IO异常
     */
    public static void decompress(File srcFile) throws IOException {
        decompress(srcFile, srcFile.getParent());
    }

    /**
     * 解压缩
     * 
     * @param srcPath  待解压文件路径
     * @param destFile 释放目录
     * @throws IOException IO异常
     */
    public static void decompress(String srcPath, File destFile) throws IOException {
        decompress(new File(srcPath), destFile);
    }

    /**
     * 解压缩
     * 
     * @param srcFile  待解压文件
     * @param destPath 释放目录路径
     * @throws IOException IO异常
     */
    public static void decompress(File srcFile, String destPath) throws IOException {
        decompress(srcFile, new File(destPath));
    }

    /**
     * 解压缩
     * 
     * @param srcPath  待解压文件路径
     * @param destPath 释放目录路径
     * @throws IOException
     */
    public static void decompress(String srcPath, String destPath) throws IOException {
        decompress(new File(srcPath), new File(destPath));
    }

    /**
     * 解压缩
     * 
     * @param srcFile  待解压文件
     * @param destFile 释放目录
     * @throws IOException IO异常
     */
    public static void decompress(File srcFile, File destFile) throws IOException {
        CheckedInputStream cis = new CheckedInputStream(new FileInputStream(srcFile), new CRC32());
        ZipInputStream zis = new ZipInputStream(cis);
        decompress(destFile, zis);
        zis.close();
    }

    /**
     * 解压缩
     * 
     * @param destFile 释放目录
     * @param zis      Zip输入流
     * @throws IOException IO异常
     */
    private static void decompress(File destFile, ZipInputStream zis) throws IOException {
        ZipEntry entry = null;
        while ((entry = zis.getNextEntry()) != null) {
            // 文件
            File dirFile = new File(destFile.getPath() + File.separator + entry.getName());

            // 文件检查
            fileProber(dirFile);

            // 检查是否为文件夹
            if (entry.isDirectory()) {
                dirFile.mkdirs(); // 创建文件夹
            } else {
                decompressFile(dirFile, zis); // 解压文件
            }

            zis.closeEntry();
        }
    }

    /**
     * 文件探针
     * 当父目录不存在时,创建目录!
     * 
     * @param dirFile 目录文件
     */
    private static void fileProber(File dirFile) {
        File parentFile = dirFile.getParentFile();
        if (!parentFile.exists()) {
            // 递归寻找上级目录
            fileProber(parentFile);
            parentFile.mkdir();
        }
    }

    /**
     * 解压缩文件
     * @param destFile 目标文件
     * @param zis      Zip输入流
     * @throws IOException IO异常
     */
    private static void decompressFile(File destFile, ZipInputStream zis) throws IOException {
        BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(destFile));

        int count;
        byte[] data = new byte[BUFFER_SIZE * bufferCoefficient];

        while ((count = zis.read(data, 0, BUFFER_SIZE * bufferCoefficient)) != -1) {
            bos.write(data, 0, count);
        }

        bos.close();
    }
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值