0
点赞
收藏
分享

微信扫一扫

Java工具类:压缩/解压缩

压缩/解压缩 在java项目中的使用。

包含了两个操作:压缩、解压缩

包含了本地文件、web文件的操作:

  1. 压缩本地文件保存到本地
  2. 压缩网络文件保存到本地
  3. 本地压缩包文件解压到本地
  4. 压缩网络文件为文件流供web下载
  5. 读取zip/jar等压缩包内的文件并打印其文本内容


import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;

/**
 * @author mengwei18
 */
@Slf4j
public class ZipUtils {

    private static final String KEY = "file.encoding";
    private static final String ENCODING = "GBK";
    private static final int BUFFER_SIZE = 2 * 1024;

    /**
     * 压缩成ZIP:压缩本地文件保存到本地专用
     *
     * @param filePaths    需要压缩的文件(本地文件)
     * @param zipFilePath 压缩成的文件名称(建议.zip结尾)
     * @throws IOException 压缩失败会抛出运行时异常
     */
    public static void zip(List<String> filePaths, String zipFilePath) throws IOException {
        OutputStream outputStream = Files.newOutputStream(Paths.get(zipFilePath));
        long start = System.currentTimeMillis();
        ZipOutputStream zos = new ZipOutputStream(outputStream);
        try {
            for (String filePath : filePaths) {
                // 如果图片路径为空则跳过
                if (StringUtils.isBlank(filePath)) {
                    continue;
                }
                compress(zos, Files.newInputStream(Paths.get(filePath)), filePath.substring(filePath.lastIndexOf("/") + 2));
            }
            zos.closeEntry();
            long end = System.currentTimeMillis();
            log.info("压缩完成,耗时:{} ms", (end - start));
        } catch (Exception e) {
            throw new RuntimeException("zip error from ZipUtils", e);
        } finally {
            try {
                zos.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }


    /**
     * 压缩成ZIP:压缩网络文件保存到本地专用
     *
     * @param fileUrls    需要压缩的文件(网络文件)
     * @param zipFilePath 压缩成的文件名称(建议.zip结尾)
     * @throws IOException 压缩失败会抛出运行时异常
     */
    public static void zipWebFiles(List<String> fileUrls, String zipFilePath) throws IOException {
        OutputStream outputStream = Files.newOutputStream(Paths.get(zipFilePath));
        long start = System.currentTimeMillis();
        ZipOutputStream zos = new ZipOutputStream(outputStream);
        try {
            for (String fileUrl : fileUrls) {
                // 如果图片路径非http开头则跳过
                if (StringUtils.isBlank(fileUrl) || !fileUrl.startsWith("http")) {
                    continue;
                }
                compress(zos, getInputStreamFromWebFile(fileUrl), fileUrl.substring(fileUrl.lastIndexOf("/") + 2));
            }
            zos.closeEntry();
            long end = System.currentTimeMillis();
            log.info("压缩完成,耗时:{} ms", (end - start));
        } catch (Exception e) {
            throw new RuntimeException("zip error from ZipUtils", e);
        } finally {
            try {
                zos.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 本地压缩包文件解压到本地
     *
     * @param zipFilePath 本地压缩包文件名称
     * @param destDir     解压后本地存储的目标目录
     */
    public static void unzip(String zipFilePath, String destDir) {
        try {
            File destDirFile = new File(destDir);
            if (!destDirFile.exists()) {
                destDirFile.mkdirs();
            }

            ZipInputStream zipIn = new ZipInputStream(Files.newInputStream(Paths.get(zipFilePath)));
            ZipEntry entry;
            while ((entry = zipIn.getNextEntry()) != null) {
                String filePath = destDir + File.separator + entry.getName();
                if (!entry.isDirectory()) {
                    extractFile(zipFilePath, zipIn, filePath);
                } else {
                    File dir = new File(filePath);
                    dir.mkdirs();
                }
                zipIn.closeEntry();
            }
            zipIn.close();
        } catch (IOException e) {
            log.error("解压异常, zipFilePath={}", zipFilePath);
        }
    }

    private static void extractFile(String zipFilePath, ZipInputStream zipIn, String filePath) {
        try (BufferedOutputStream bos = new BufferedOutputStream(Files.newOutputStream(Paths.get(filePath)))) {
            byte[] bytesIn = new byte[4096];
            int read;
            while ((read = zipIn.read(bytesIn)) != -1) {
                bos.write(bytesIn, 0, read);
            }
        } catch (Exception ignore) {
            log.error("解压中发现不存在的文件, zipFilePath={}, filePath={}", zipFilePath, filePath);
        }
    }

    /**
     * 压缩成ZIP:web请求专用,会转化为文件流供web下载
     *
     * @param fileUrls 需要压缩的文件(网络文件)
     * @param response 文件流输出的response
     * @throws IOException 压缩失败会抛出运行时异常
     */
    public static void toZipResponse(List<String> fileUrls, HttpServletResponse response) throws IOException {
        long start = System.currentTimeMillis();
        ZipOutputStream zos = new ZipOutputStream(response.getOutputStream());
        try {
            for (String fileUrl : fileUrls) {
                // 如果图片路径非http开头则跳过
                if (StringUtils.isBlank(fileUrl) || !fileUrl.startsWith("http")) {
                    continue;
                }
                compress(zos, getInputStreamFromWebFile(fileUrl), fileUrl.substring(fileUrl.lastIndexOf("/") + 2));
            }
            zos.closeEntry();
            long end = System.currentTimeMillis();
            log.info("压缩完成,耗时:{} ms", (end - start));
        } catch (Exception e) {
            throw new RuntimeException("zip error from ZipUtils", e);
        } finally {
            try {
                zos.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    private static InputStream getInputStreamFromWebFile(String url) {
        if (StringUtils.isBlank(url)) {
            return null;
        }
        URLConnection con;
        HttpURLConnection httpCon;
        try {
            System.setProperty(KEY, ENCODING);
            con = new URL(url).openConnection();
            con.setConnectTimeout(3000);
            con.setUseCaches(false);
            con.setDefaultUseCaches(false);
            if (con instanceof HttpURLConnection) {
                httpCon = (HttpURLConnection) con;
                httpCon.setInstanceFollowRedirects(true);
                if (httpCon.getResponseCode() >= 300) {
                    System.out.println("URL:" + url + ",HTTP Request is not success, Response code is " + httpCon.getResponseCode());
                } else {
                    return httpCon.getInputStream();
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 递归压缩方法
     *
     * @param zos zip输出流
     */
    private static void compress(ZipOutputStream zos, InputStream fileInputStream, String fileName) throws Exception {
        if (fileInputStream == null || StringUtils.isBlank(fileName)) {
            return;
        }
        byte[] buf = new byte[BUFFER_SIZE];
        // 向zip输出流中添加一个zip实体,构造器中name为zip实体的文件的名字
        zos.putNextEntry(new ZipEntry(fileName));
        // copy文件到zip输出流中
        int len;
        while ((len = fileInputStream.read(buf)) != -1) {
            zos.write(buf, 0, len);
        }
        // Complete the entry
        fileInputStream.close();
    }

    /**
     * 读取zip/jar等压缩包内的文件并打印其文本内容
     *
     * @param zipFilePath 本地压缩包文件名称
     */
    public static void readZipFileContent(String zipFilePath) throws Exception {
        ZipFile zipFile = new ZipFile(zipFilePath);
        InputStream inputStream = new BufferedInputStream(Files.newInputStream(Paths.get(zipFilePath)));
        ZipInputStream zipInputStream = new ZipInputStream(inputStream);
        java.util.zip.ZipEntry zipEntry;
        while ((zipEntry = zipInputStream.getNextEntry()) != null) {
            if (!zipEntry.isDirectory()) {
                PrintUtil.print("file - " + zipEntry.getName() + " : " + zipEntry.getSize() + " bytes");
                long size = zipEntry.getSize();
                if (size > 0) {
                    BufferedReader br = new BufferedReader(new InputStreamReader(zipFile.getInputStream(zipEntry)));
                    String line;
                    while ((line = br.readLine()) != null) {
                        PrintUtil.print(line);
                    }
                    br.close();
                }
                PrintUtil.print();
            }
        }
        zipInputStream.closeEntry();
        zipInputStream.close();
        inputStream.close();
        zipFile.close();
    }

}

举报

相关推荐

0 条评论