Java实现压缩与解压缩工具类

package com.bfd.knowl.common.utils;

import java.io.*;
import java.util.ArrayList;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;

import com.bfd.bdos.common.logger.LogType;
import com.bfd.bdos.common.logger.LogUtil;

/**
 * 压缩文件夹工具类
 *
 * @author ming.chang
 * @since 2020/12/5 10:37
 */
public class ZipUtils {

    /**
     * 缓冲器大小
     */
    private static final int BUFFER = 512;

    /**
     * 压缩方法
     * (可以压缩空的子目录)
     *
     * @param srcPath     压缩源路径
     * @param zipFileName 目标压缩文件
     * @return
     */
    public static boolean zip(String srcPath, String zipFileName) {
        LogUtil.debug(LogType.Server,"zip compressing...");
        File srcFile = new File(srcPath);
        // 扫描所有要压缩的文件
        List<File> fileList = getAllFiles(srcFile);
        // 缓冲器
        byte[] buffer = new byte[BUFFER];
        ZipEntry zipEntry = null;
        // 每次读出来的长度
        int readLength = 0;
        try {
            ZipOutputStream zipOutputStream = new ZipOutputStream(new FileOutputStream(zipFileName));
            for (File file : fileList) {
                // 若是文件,则压缩这个文件
                if (file.isFile()) {
                    zipEntry = new ZipEntry(getRelativePath(srcPath, file));
                    zipEntry.setSize(file.length());
                    zipEntry.setTime(file.lastModified());
                    zipOutputStream.putNextEntry(zipEntry);
                    InputStream inputStream = new BufferedInputStream(new FileInputStream(file));
                    while ((readLength = inputStream.read(buffer, 0, BUFFER)) != -1) {
                        zipOutputStream.write(buffer, 0, readLength);
                    }
                    inputStream.close();
                    LogUtil.debug(LogType.Server,"file compressed: " + file.getCanonicalPath());
                } else {
                    //若是目录(即空目录)则将这个目录写入zip条目
                    zipEntry = new ZipEntry(getRelativePath(srcPath, file) + "/");
                    zipOutputStream.putNextEntry(zipEntry);
                    LogUtil.debug(LogType.Server,"dir compressed: " + file.getCanonicalPath() + "/");
                }
            }
            zipOutputStream.close();
        } catch (FileNotFoundException e) {
            LogUtil.error(LogType.Server,"zip fail!" + e);
            return false;
        } catch (IOException e) {
            System.out.println(e.getMessage());
            e.printStackTrace();
            LogUtil.error(LogType.Server,"zip fail!" + e);
            return false;
        }
        LogUtil.debug(LogType.Server,"zip success!" );
        return true;
    }

    /**
     * 解压缩方法
     *
     * @param zipFileName 压缩文件名
     * @param dstPath     解压目标路径
     * @return
     */
    public static boolean unzip(String zipFileName, String dstPath) {
        LogUtil.debug(LogType.Server,"zip uncompressing..." );
        try {
            ZipInputStream zipInputStream = new ZipInputStream(new FileInputStream(zipFileName));
            ZipEntry zipEntry = null;
            byte[] buffer = new byte[BUFFER];
            int readLength = 0;
            while ((zipEntry = zipInputStream.getNextEntry()) != null) {
                //若是zip条目目录,则需创建这个目录
                if (zipEntry.isDirectory()) {
                    File dir = new File(dstPath + "/" + zipEntry.getName());
                    if (!dir.exists()) {
                        dir.mkdirs();
                        LogUtil.info(LogType.Server,"mkdirs: " + dir.getCanonicalPath());
                        continue;
                    }
                }
                //若是文件,则需创建该文件
                File file = createFile(dstPath, zipEntry.getName());
                LogUtil.debug(LogType.Server,"file created: " + file.getCanonicalPath());
                OutputStream outputStream = new FileOutputStream(file);
                while ((readLength = zipInputStream.read(buffer, 0, BUFFER)) != -1) {
                    outputStream.write(buffer, 0, readLength);
                }
                outputStream.close();
                LogUtil.debug(LogType.Server,"file uncompressed: " + file.getCanonicalPath());
            }
        } catch (FileNotFoundException e) {
            LogUtil.error(LogType.Server,"unzip fail!"+e);
            return false;
        } catch (IOException e) {
            LogUtil.error(LogType.Server,"unzip fail!"+e);
            return false;
        }
        LogUtil.debug(LogType.Server,"unzip success!");
        return true;
    }

    /**
     * 取的给定源目录下的所有文件及空的子目录
     * 递归实现
     *
     * @param srcFile
     * @return
     */
    private static List<File> getAllFiles(File srcFile) {
        List<File> fileList = new ArrayList<>();
        File[] tmp = srcFile.listFiles();

        for (int i = 0; i < tmp.length; i++) {

            if (tmp[i].isFile()) {
                fileList.add(tmp[i]);
                System.out.println("add file: " + tmp[i].getName());
            }

            if (tmp[i].isDirectory()) {
                // 若不是空目录,则递归添加其下的目录和文件
                if (tmp[i].listFiles().length != 0) {
                    fileList.addAll(getAllFiles(tmp[i]));
                } else {
                    // 若是空目录,则添加这个目录到fileList
                    fileList.add(tmp[i]);
                    System.out.println("add empty dir: " + tmp[i].getName());
                }
            }
        }
        return fileList;
    }

    /**
     * 取相对路径
     * 依据文件名和压缩源路径得到文件在压缩源路径下的相对路径
     *
     * @param dirPath 压缩源路径
     * @param file
     * @return 相对路径
     */
    private static String getRelativePath(String dirPath, File file) {
        File dir = new File(dirPath);
        String relativePath = file.getName();
        StringBuilder sb = new StringBuilder(relativePath);
        while (true) {
            file = file.getParentFile();
            if (file == null) {
                break;
            }
            if (file.equals(dir)) {
                break;
            } else {
                sb.append(file.getName()).append("/").append(relativePath);
            }
        }
        return sb.toString();
    }
    /**
     * 创建文件
     * 根据压缩包内文件名和解压缩目的路径,创建解压缩目标文件,
     * 生成中间目录
     *
     * @param dstPath  解压缩目的路径
     * @param fileName 压缩包内文件名
     * @return 解压缩目标文件
     * @throws IOException
     */
    private static File createFile(String dstPath, String fileName) throws IOException {
        // 将文件名的各级目录分解
        String[] dirs = fileName.split("/");
        File file = new File(dstPath);
        // 文件有上级目录
        if (dirs.length > 1) {
            for (int i = 0; i < dirs.length - 1; i++) {
                // 依次创建文件对象知道文件的上一级目录
                file = new File(file, dirs[i]);
            }

            if (!file.exists()) {
                // 文件对应目录若不存在,则创建
                file.mkdirs();
                System.out.println("mkdirs: " + file.getCanonicalPath());
            }
            // 创建文件
            file = new File(file, dirs[dirs.length - 1]);
            return file;
        } else {
            if (!file.exists()) {
                //若目标路径的目录不存在,则创建
                file.mkdirs();
                System.out.println("mkdirs: " + file.getCanonicalPath());
            }
            //创建文件
            file = new File(file, dirs[0]);
            return file;
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值