Java教程

Java多线程Zip压缩

本文主要是介绍Java多线程Zip压缩,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

Java多线程Zip压缩

  • Zip压缩
  • 多线程压缩
  • 线程池

依赖 maven坐标

<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-compress</artifactId>
    <version>1.20</version>
</dependency>

压缩工具包代码 ZipCompressUtils.java

package com.test.utils;

import org.apache.commons.compress.archivers.zip.ParallelScatterZipCreator;
import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
import org.apache.commons.compress.archivers.zip.ZipArchiveOutputStream;
import org.apache.commons.compress.parallel.InputStreamSupplier;
import org.apache.commons.io.input.NullInputStream;

import java.io.*;
import java.util.concurrent.*;
import java.util.zip.Deflater;

/**
 * @author youlingdada youlingdada@163.com
 * @version 1.0
 * @createDate 2022/1/30 11:15
 */
public class ZipCompressUtils {
    /**
     * 压缩文件夹
     *
     * @param zipOutName zip输出路径
     * @param paths      将要压缩的路径
     * @throws IOException
     * @throws ExecutionException
     * @throws InterruptedException
     */
    public static void compressFiles(String zipOutName, String... paths) throws IOException, ExecutionException, InterruptedException {
//        创建一个线程池对象
        ExecutorService executor = new ThreadPoolExecutor(5, 10, 60, TimeUnit.SECONDS, new LinkedBlockingQueue<>(20), Executors.defaultThreadFactory(), new ThreadPoolExecutor.CallerRunsPolicy());
//        压缩等级默认为速度优先
        compressFiles(zipOutName, executor, Deflater.BEST_SPEED, paths);
    }

    /**
     * 自定义线程池
     *
     * @param zipOutName
     * @param executorService 线程池实现对象
     * @param paths
     * @throws IOException
     * @throws ExecutionException
     * @throws InterruptedException
     */
    public static void compressFiles(String zipOutName, ExecutorService executorService, int level, String... paths) throws IOException, ExecutionException, InterruptedException {
//      创建用于多线程压缩文件的对象
        ParallelScatterZipCreator parallelScatterZipCreator = new ParallelScatterZipCreator(executorService);
//        输出文件流
        OutputStream outputStream = new FileOutputStream(zipOutName);
//        输出Zip文件流
        ZipArchiveOutputStream zipArchiveOutputStream = new ZipArchiveOutputStream(outputStream);
//        设置压缩等级
        zipArchiveOutputStream.setLevel(level);
//        设置压缩的字符编码
        zipArchiveOutputStream.setEncoding("UTF-8");
//        循环压缩各个路径的文件
        for (String path : paths) {
            File temp = new File(path);
            compress(parallelScatterZipCreator, temp, temp.getName());
        }
//        将数据写入zip输出流
        parallelScatterZipCreator.writeTo(zipArchiveOutputStream);
//        相关流的关闭
        zipArchiveOutputStream.close();
        outputStream.close();
    }

    /**
     * 自定义线程创建工厂
     *
     * @param zipOutName
     * @param factory    线程创建工厂
     * @param level      压缩等级
     * @param paths
     * @throws IOException
     * @throws ExecutionException
     * @throws InterruptedException
     */
    public static void compressFiles(String zipOutName, ThreadFactory factory, int level, String... paths) throws IOException, ExecutionException, InterruptedException {
        ExecutorService executor = new ThreadPoolExecutor(5, 10, 60, TimeUnit.SECONDS, new LinkedBlockingQueue<>(20), factory, new ThreadPoolExecutor.CallerRunsPolicy());
        compressFiles(zipOutName, executor, level, paths);
    }


    /**
     * 遍历压缩
     *
     * @param parallelScatterZipCreator 线程池压缩对象
     * @param inputFile                 将要压缩的文件路径,绝对路径
     * @param relativePath              相对与压缩包内的路径
     * @throws IOException
     * @throws ExecutionException
     * @throws InterruptedException
     */
    protected static void compress(ParallelScatterZipCreator parallelScatterZipCreator, File inputFile, String relativePath) throws IOException, ExecutionException, InterruptedException {
//        文件流为空,返回
        if (inputFile == null) {
            return;
        }
//        文件为文件夹,递归遍历文件
        if (inputFile.isDirectory()) {
//            获取文件内的所有文件
            File[] files = inputFile.listFiles();
            if (files == null) {
                return;
            }
//            遍历处理文件
            for (File file : files) {
                if (file.isDirectory()) {
                    compress(parallelScatterZipCreator, new File(inputFile.getAbsolutePath() + "/" + file.getName()), relativePath + "/" + file.getName());
                } else {
//                    转化为InputStreamSupplier对象
                    final InputStreamSupplier inputStreamSupplier = () -> {
                        try {
                            return new FileInputStream(file);
                        } catch (FileNotFoundException e) {
                            e.printStackTrace();
                            return new NullInputStream(0);
                        }
                    };
//                    添加ZipArchiveEntity对象,这里的构造函数的值,name属性,是相对于zip文件内的路径
                    ZipArchiveEntry zipArchiveEntry = new ZipArchiveEntry(relativePath + "/" + file.getName());
//                    设置压缩算法
                    zipArchiveEntry.setMethod(ZipArchiveEntry.DEFLATED);
//                    设置未压缩文件的大小
                    zipArchiveEntry.setSize(file.length());
//                    添加添加ZipArchiveEntity对象到多线程压缩中
                    parallelScatterZipCreator.addArchiveEntry(zipArchiveEntry, inputStreamSupplier);
                }
            }
        } else {
//            当是文件时,直接处理
            final InputStreamSupplier inputStreamSupplier = () -> {
                try {
                    return new FileInputStream(inputFile);
                } catch (FileNotFoundException e) {
                    e.printStackTrace();
                    return new NullInputStream(0);
                }
            };
            ZipArchiveEntry zipArchiveEntry = new ZipArchiveEntry(relativePath + "/" + inputFile.getName());
            zipArchiveEntry.setMethod(ZipArchiveEntry.DEFLATED);
            zipArchiveEntry.setSize(inputFile.length());
            parallelScatterZipCreator.addArchiveEntry(zipArchiveEntry, inputStreamSupplier);
        }
    }
}
这篇关于Java多线程Zip压缩的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!