文件压缩与解压

package com.sg.test.utils;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.*;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import java.util.Objects;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import java.util.zip.ZipOutputStream;

/***
 * @date 2020/1/08
 **/
public class ZipUtil {

    private static final Logger logger = LoggerFactory.getLogger(ZipUtil.class);
    /** 缓冲器大小*/
    private static final int BUFFER = 4096;

    public static void unzip(String zipFileName, String outputDirectory) {
        try {
            ZipFile zipFile = new ZipFile(new File(zipFileName), Charset.forName("GBK"));
            OutputStream outputStream;
            InputStream inputStream;
            Enumeration<? extends ZipEntry>  entries= zipFile.entries();
            ZipEntry zn;
            while (entries.hasMoreElements()) {
                zn = entries.nextElement();
                if (zn.isDirectory()) {
                    String name = zn.getName();
                    name = name.substring(0, name.length() - 1);
                    File f = new File(outputDirectory + File.separator + name);
                    f.mkdir();
                    logger.debug("mkdir " + outputDirectory + File.separator + name);
                } else {
                    File f = new File(outputDirectory + File.separator + zn.getName());
                    f.createNewFile();
                    logger.debug("f:" + f);
                    outputStream = new FileOutputStream(f);
                    inputStream = zipFile.getInputStream(zn);
                    int size = 0;
                    byte[] buffer = new byte[BUFFER];
                    while ((size = inputStream.read(buffer)) != -1) {
                        outputStream.write(buffer, 0, size);
                    }
                    outputStream.flush();
                    inputStream.close();
                    outputStream.close();
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 压缩方法
     * (可以压缩空的子目录)
     * @param srcPath     压缩源路径
     * @param zipFileName 目标压缩文件
     */
    public static boolean zip(String srcPath, String zipFileName) {
        System.out.println("zip compressing...");
        File srcFile = new File(srcPath);
        //所有要压缩的文件
        List<File> fileList = getAllFiles(srcFile);
        //缓冲器
        byte[] buffer = new byte[BUFFER];
        ZipEntry zipEntry;
        //每次读出来的长度
        int readLength;
        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();
                    System.out.println("file compressed: " + file.getCanonicalPath());
                } else {//若是目录(即空目录)则将这个目录写入zip条目
                    zipEntry = new ZipEntry(getRelativePath(srcPath, file) + "/");
                    zipOutputStream.putNextEntry(zipEntry);
                    System.out.println("dir compressed: " + file.getCanonicalPath() + "/");
                }
            }
            zipOutputStream.close();
        } catch (IOException e) {
            System.out.println(e.getMessage());
            e.printStackTrace();
            System.out.println("zip fail!");
            return false;
        }
        System.out.println("zip success!");
        return true;
    }


    /**
     * 取的给定源目录下的所有文件及空的子目录
     * 递归实现
     * @param srcFile 文件
     */
    private static List<File> getAllFiles(File srcFile) {
        List<File> fileList = new ArrayList<>();
        File[] tmp = srcFile.listFiles();
        assert tmp != null;
        for (File file : tmp) {
            if (file.isFile()) {
                fileList.add(file);
                System.out.println("add file: " + file.getName());
            }
            if (file.isDirectory()) {
                //若不是空目录,则递归添加其下的目录和文件
                if (Objects.requireNonNull(file.listFiles()).length != 0) {
                    fileList.addAll(getAllFiles(file));
                } else {//若是空目录,则添加这个目录到fileList
                    fileList.add(file);
                    System.out.println("add empty dir: " + file.getName());
                }
            }
        }
        return fileList;
    }

    /**
     * 取相对路径
     * 依据文件名和压缩源路径得到文件在压缩源路径下的相对路径
     * @param dirPath 压缩源路径
     * @param file    文件
     * @return 相对路径
     */
    private static String getRelativePath(String dirPath, File file) {
        File dir = new File(dirPath);
        StringBuilder relativePath = new StringBuilder(file.getName());
        while (true) {
            file = file.getParentFile();
            if (file == null) {
                break;
            }
            if (file.equals(dir)) {
                break;
            } else {
                relativePath.insert(0, file.getName() + "/");
            }
        }
        return relativePath.toString();
    }
}
    /**
     * 删除文件夹下的所有文件
     * @param fileDir 文件夹
     */
    private static void deleteAllFiles(String fileDir) {
        File file = new File(fileDir);
        if (file.isFile()) {
            file.delete();
        } else {
            File[] files = file.listFiles();
            for (File f : files) {
                deleteAllFiles(fileDir + File.separator + f.getName());
            }
            file.delete();
        }
    }

测试

	//解压问价
    @Test
    public void unzip() {
        String filePath = "F:\\新建文件夹";
        String fileName = "file.zip";
        ZipUtil.unzip(filePath + File.separator + fileName, filePath);
    }
	//压缩文件
    @Test
    public void zip() throws IOException {
        String filePath = "F:\\新建文件夹";
        String fileName = "file.zip";
        ZipUtil.zip(filePath,filePath+File.separator+fileName);
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值