JAVA 操作 zip

zip4j源码地址

 <dependency>
    <groupId>net.lingala.zip4j</groupId>
    <artifactId>zip4j</artifactId>
    <version>2.7.0</version>
</dependency>



 

import java.io.*;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;

import net.lingala.zip4j.ZipFile;
import net.lingala.zip4j.io.outputstream.ZipOutputStream;
import net.lingala.zip4j.model.enums.AesKeyStrength;
import net.lingala.zip4j.model.enums.CompressionLevel;
import net.lingala.zip4j.model.enums.CompressionMethod;
import net.lingala.zip4j.model.enums.EncryptionMethod;

import net.lingala.zip4j.exception.ZipException;
import net.lingala.zip4j.model.FileHeader;
import net.lingala.zip4j.model.ZipParameters;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.StringUtils;

/**
 * 压缩与解压缩文件工具类
 *
 * @author wh
 */
public class ZipUtils {

    /**
     * 压缩文件 2 OutputStream
     *
     * @param outputStream outputStream
     * @param filesToAdd   添加的文件
     * @param password     设置密码
     */
    public static void zipOutputStream(OutputStream outputStream, List<File> filesToAdd, String password) {
        ZipParameters zipParameters = new ZipParameters();
        zipParameters.setCompressionMethod(CompressionMethod.DEFLATE);
        zipParameters.setCompressionLevel(CompressionLevel.NORMAL);
        if (StringUtils.isNotEmpty(password)) {
            zipParameters.setEncryptionMethod(EncryptionMethod.AES);
            zipParameters.setAesKeyStrength(AesKeyStrength.KEY_STRENGTH_256);
            zipParameters.setEncryptFiles(true);
        }
        try (ZipOutputStream zos = initializeZipOutputStream(outputStream, password)) {
            for (File fileToAdd : filesToAdd) {
                // Entry size has to be set if you want to add entries of STORE compression method (no compression)
                // This is not required for deflate compression
                if (zipParameters.getCompressionMethod() == CompressionMethod.STORE) {
                    zipParameters.setEntrySize(fileToAdd.length());
                }
                do_file_toZip(fileToAdd, zos, zipParameters, fileToAdd.getName());
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private static ZipOutputStream initializeZipOutputStream(OutputStream outputStream, String password) throws IOException {
        if (StringUtils.isNotEmpty(password)) {
            return new ZipOutputStream(outputStream, password.toCharArray());
        }
        return new ZipOutputStream(outputStream);
    }

    private static void do_file_toZip(File sourceFile, ZipOutputStream zos, ZipParameters zipParameters, String name) throws Exception {
        byte[] buf = new byte[4096];
        if (sourceFile.isFile()) {
            // 向zip输出流中添加一个zip实体,构造器中name为zip实体的文件的名字
            zipParameters.setFileNameInZip(name);
            zos.putNextEntry(zipParameters);
            // copy文件到zip输出流中
            int readLen;
            try (InputStream inputStream = new FileInputStream(sourceFile)) {
                while ((readLen = inputStream.read(buf)) != -1) {
                    zos.write(buf, 0, readLen);
                }
            }
            zos.closeEntry();
        } else {
            File[] listFiles = sourceFile.listFiles();
            if (listFiles == null || listFiles.length == 0) {
                // 需要保留原来的文件结构时,需要对空文件夹进行处理
                zipParameters.setFileNameInZip(name + "/");
                zos.putNextEntry(zipParameters);
                zos.closeEntry();
            } else {
                for (File file : listFiles) {
                    // 判断是否需要保留原来的文件结构  注意:file.getName()前面需要带上父文件夹的名字加一斜杠, 不然最后压缩包中就不能保留原来的文件结构, 所有文件都跑到压缩包根目录下了
                    do_file_toZip(file, zos, zipParameters, name + "/" + file.getName());
                }
            }
        }
    }

    /**
     * 根据给定密码压缩文件(s)到指定目录
     *
     * @param destFileName 压缩文件存放绝对路径 e.g.:D:/upload/zip/demo.zip
     * @param passwd       密码(可为空)
     * @param files        单个文件或文件数组
     * @return 最终的压缩文件存放的绝对路径, 如果为null则说明压缩失败.
     */
    public static String compress(String destFileName, String passwd, File... files) {
        try {
            ZipParameters zipParameters = new ZipParameters();
            zipParameters.setCompressionMethod(CompressionMethod.DEFLATE);
            zipParameters.setCompressionLevel(CompressionLevel.NORMAL);
            zipParameters.setIncludeRootFolder(true);
            ZipFile zipFile;
            if (StringUtils.isNotBlank(passwd)) {
                zipParameters.setEncryptFiles(true);
                zipParameters.setEncryptionMethod(EncryptionMethod.AES);
                zipParameters.setAesKeyStrength(AesKeyStrength.KEY_STRENGTH_256);
                zipFile = new ZipFile(destFileName, passwd.toCharArray());
            } else {
                zipParameters.setEncryptFiles(false);
                zipParameters.setEncryptionMethod(EncryptionMethod.NONE);
                zipFile = new ZipFile(destFileName);
            }
            zipFile.setCharset(StandardCharsets.UTF_8);
            for (File file : files) {
                if (file.exists()) {
                    if (file.isDirectory()) {
                        zipFile.addFolder(file, zipParameters);
                    } else {
                        zipFile.addFile(file, zipParameters);
                    }
                }
            }
            return destFileName;
        } catch (ZipException e) {
            e.printStackTrace();
        }

        return null;
    }

    /**
     * 根据给定密码压缩文件(s)到指定位置
     *
     * @param destFileName 压缩文件存放绝对路径 e.g.:D:/upload/zip/demo.zip
     * @param passwd       密码(可为空)
     * @param filePaths    单个文件路径或文件路径数组
     * @return 最终的压缩文件存放的绝对路径, 如果为null则说明压缩失败.
     */
    public static String compress(String destFileName, String passwd, String... filePaths) {
        int size = filePaths.length;
        File[] files = new File[size];
        for (int i = 0; i < size; i++) {
            files[i] = new File(filePaths[i]);
        }
        return compress(destFileName, passwd, files);
    }

    /**
     * 根据给定密码压缩文件(s)到指定位置
     *
     * @param destFileName 压缩文件存放绝对路径 e.g.:D:/upload/zip/demo.zip
     * @param passwd       密码(可为空)
     * @param folder       文件夹
     * @return 最终的压缩文件存放的绝对路径, 如果为null则说明压缩失败.
     */
    public static String compressFolder(String destFileName, String passwd, File folder) {
        if (folder.exists()) {
            File[] files = folder.listFiles();
            // 遍历folder文件夹下所有的文件、文件夹
            return compress(destFileName, passwd, files);
        }
        return null;
    }

    /**
     * 根据所给密码解压zip压缩包到指定目录
     * <p>
     * 如果指定目录不存在,可以自动创建,不合法的路径将导致异常被抛出
     *
     * @param zipFile zip压缩包绝对路径
     * @param dest    指定解压文件夹位置
     * @param passwd  密码(可为空)
     * @return 解压后的文件数组
     * @throws ZipException
     */
    public static File[] deCompress(File zipFile, String dest, String passwd) throws ZipException {
        // 1.判断指定目录是否存在
        File destDir = new File(dest);
        if (destDir.isDirectory() && !destDir.exists()) {
            destDir.mkdir();
        }
        // 2.初始化zip工具
        ZipFile zFile = new ZipFile(zipFile);
        zFile.setCharset(StandardCharsets.UTF_8);
        if (!zFile.isValidZipFile()) {
            throw new ZipException("压缩文件不合法,可能被损坏.");
        }
        // 3.判断是否已加密
        if (zFile.isEncrypted()) {
            zFile.setPassword(passwd.toCharArray());
        }
        // 4.解压所有文件
        zFile.extractAll(dest);
        List<FileHeader> headerList = zFile.getFileHeaders();
        List<File> extractedFileList = new ArrayList<>();
        for (FileHeader fileHeader : headerList) {
            if (!fileHeader.isDirectory()) {
                extractedFileList.add(new File(destDir, fileHeader.getFileName()));
            }
        }
        File[] extractedFiles = new File[extractedFileList.size()];
        extractedFileList.toArray(extractedFiles);
        return extractedFiles;
    }

    /**
     * 解压无密码的zip压缩包到指定目录
     *
     * @param zipFile zip压缩包
     * @param dest    指定解压文件夹位置
     * @return 解压后的文件数组
     * @throws ZipException
     */
    public static File[] deCompress(File zipFile, String dest) {
        try {
            return deCompress(zipFile, dest, null);
        } catch (ZipException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 根据所给密码解压zip压缩包到指定目录
     *
     * @param zipFilePath zip压缩包绝对路径
     * @param dest        指定解压文件夹位置
     * @param passwd      压缩包密码
     * @return 解压后的所有文件数组
     */
    public static File[] deCompress(String zipFilePath, String dest, String passwd) {
        try {
            return deCompress(new File(zipFilePath), dest, passwd);
        } catch (ZipException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 无密码解压压缩包到指定目录
     *
     * @param zipFilePath zip压缩包绝对路径
     * @param dest        指定解压文件夹位置
     * @return 解压后的所有文件数组
     */
    public static File[] deCompress(String zipFilePath, String dest) {
        try {
            return deCompress(new File(zipFilePath), dest, null);
        } catch (ZipException e) {
            e.printStackTrace();
        }
        return null;
    }

    public static void main(String[] args) throws IOException {
        // 压缩demo1 自定义文件夹
        // 创建一个 rootTemp 缓存目录
        String rootTemp = "D:/xxxproject";
        // 获取缓存目录文件夹下的全部文件结构和数据
        File file = new File(rootTemp);
        //模拟添加多个文件夹目录
        for (int i = 0; i < 3; i++) {
            // 需要被压缩的源文件
            File file1 = new File("D:/test.xls");
            // 自定义文件夹
            File file2 = new File(rootTemp + "/" + i + "/a1/a2");
            // 将源文件复制到自定义文件夹内, 有多个文件的的话都复制进来
            FileUtils.copyFileToDirectory(file1, file2);
            // 模拟创建空文件夹
            File file3 = new File(rootTemp + "/" + i + "/b1/b2");
            file3.mkdirs();
        }
        compressFolder(rootTemp + ".zip", "", file);
        // 压缩后删除缓存目录全部的数据
        FileUtils.deleteDirectory(file);

        //压缩demo2 到OutputStream
        List<File> list = new ArrayList<>();
        list.add(new File("D:/360SoftMgrGame"));
        zipOutputStream(new FileOutputStream("D:/sign.zip"),  list, "");

        // 解压
        //deCompress("D:/sign.zip", "D:/unzip", "");
        System.err.println("完成");
    }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java 1.8版本中引入了压缩和解压缩文件的功能,我们可以使用java.util.zip包中的类来使用该功能。 1. 压缩文件: 可以使用ZipOutputStream类来创建一个新的压缩文件,并向其中添加文件。 首先,我们需要创建一个ZipOutputStream对象,并传入一个文件输出流对象作为参数。接着,可以使用putNextEntry()方法来设置下一个要添加的文件的条目。 然后,我们可以使用write()方法将文件的内容写入到压缩文件中。最后,我们需要使用closeEntry()方法关闭当前条目,并继续添加下一个文件。 2. 解压缩文件: 可以使用ZipInputStream类来解压缩一个zip文件中的内容。 首先,我们需要创建一个ZipInputStream对象,并传入一个文件输入流对象,指向要解压缩的zip文件。接着,可以使用getNextEntry()方法获取到zip文件中的下一个文件的条目。 然后,我们可以使用read()方法从zip文件中读取文件的内容,并将其写入到解压缩后的文件中。读取完一个文件后,我们需要使用closeEntry()方法关闭当前条目,并继续解压下一个文件。 总结:Java 1.8版本中的zip功能提供了方便的接口来压缩和解压缩文件。通过使用java.util.zip包中的ZipOutputStream和ZipInputStream类,我们可以轻松地完成这些操作。无论是压缩还是解压缩文件,我们都可以通过一些简单的步骤来实现此功能。使用这些类,我们可以有效地管理、处理和操作zip文件。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值