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);
        }
    }
}
  • 6
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
Java调用Zip类批量压缩多个文件,此前有一个是压缩单个文件,也可参考,相关代码中可找到此源码。   public class ZipDemo extends JFrame{   JFileChooser fileChooser; //文件选择器   JList fileList; //待压缩的文件列表   Vector files; //文件数据(待压缩文件)   JButton jbAdd; //增加文件按钮   JButton jbDelete; //删除文件按钮   JButton jbZip; //压缩按钮   JTextField target; //目标文件文本域   public ZipDemo(){   super("用ZIP压缩多个文件"); //调用父类构造函数   fileChooser=new JFileChooser(); //实例化文件选择器   files=new Vector(); //实例化文件数据Vector   fileList=new JList(files); //实例化已选择文件列表   jbAdd=new JButton("增加"); //实例化按钮组件   jbDelete=new JButton("删除");   jbZip=new JButton("压缩");   target=new JTextField(18);   JPanel panel=new JPanel(); //实例化面板,用于容纳按钮   panel.add(jbAdd); //增加组件到面板上   panel.add(jbDelete);   panel.add(jbZip);   JPanel panel2=new JPanel();   panel2.add(new JLabel("目标文件"));   panel2.add(target);   JScrollPane jsp=new JScrollPane(fileList);   Container container=getContentPane(); //得到容器   container.add(panel2,BorderLayout.NORTH); //增加组件到容器   container.add(jsp,BorderLayout.CENTER);   container.add(panel,BorderLayout.SOUTH);   jsp.setBorder(BorderFactory.createEmptyBorder(10,10,10,10)); //设置边界
下面是一个使用Java多线程压缩文件夹的示例代码: ```java import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.zip.ZipEntry; import java.util.zip.ZipOutputStream; public class FolderCompressor { private static final int THREAD_POOL_SIZE = 5; public static void main(String[] args) { String sourceFolder = "/path/to/source/folder"; String zipFile = "/path/to/output/zip/file.zip"; compressFolder(sourceFolder, zipFile); } public static void compressFolder(String sourceFolder, String zipFile) { File folderToCompress = new File(sourceFolder); File zipOutputFile = new File(zipFile); if (!folderToCompress.exists()) { System.out.println("Source folder does not exist."); return; } try (ZipOutputStream zipOutputStream = new ZipOutputStream(new FileOutputStream(zipOutputFile))) { ExecutorService executorService = Executors.newFixedThreadPool(THREAD_POOL_SIZE); compressFolder(folderToCompress, folderToCompress.getName(), zipOutputStream, executorService); executorService.shutdown(); } catch (IOException e) { e.printStackTrace(); } } private static void compressFolder(File folder, String parentFolder, ZipOutputStream zipOutputStream, ExecutorService executorService) throws IOException { for (File file : folder.listFiles()) { if (file.isDirectory()) { compressFolder(file, parentFolder + "/" + file.getName(), zipOutputStream, executorService); continue; } executorService.execute(() -> { try (FileInputStream fileInputStream = new FileInputStream(file)) { ZipEntry zipEntry = new ZipEntry(parentFolder + "/" + file.getName()); zipOutputStream.putNextEntry(zipEntry); byte[] buffer = new byte[1024]; int length; while ((length = fileInputStream.read(buffer)) > 0) { zipOutputStream.write(buffer, 0, length); } zipOutputStream.closeEntry(); } catch (IOException e) { e.printStackTrace(); } }); } } } ``` 请将`/path/to/source/folder`替换为要压缩的文件夹路径,并将`/path/to/output/zip/file.zip`替换为输出的压缩文件路径。该代码使用了固定大小的线程池来并行压缩文件夹中的文件。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值