java 将文件夹进行压缩,按指定大小进行分卷压缩

使用方法:
SplitZip splitZip = new SplitZip();
splitZip.start(file.getPath(),file.getPath());

package ext.xxx.util;

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

import static org.apache.commons.lang3.StringUtils.isBlank;

/**
 * 分卷压缩工具
 */
public class SplitZip {
    private static final int MAX_ZIP_SIZE = 1024 * 1024 * 300; // 300MB,可以改为自己想要的大小
    private  ZipOutputStream currentZipOutputStream = null;
    private  File currentZipFile = null;
    private  long totalBytesWritten = 0;
    private  int currentZipCount = 0;
    private  String basePath = ""; // 基本路径,用于在ZIP中保持相对路径

    private String outZipName = "";//输出压缩包的名称

    public void addFileToZip(File fileToAdd, String parentPath) throws IOException {
        long approximateFileSize = getApproximateFileSize(fileToAdd);//计算要压缩的文件(文件夹)大小
        if (currentZipOutputStream == null || (totalBytesWritten + approximateFileSize > MAX_ZIP_SIZE && totalBytesWritten != 0)) {
            closeCurrentZip();
            openNewZip();
        }

        if (fileToAdd.isDirectory()) {
            File[] files = fileToAdd.listFiles();
            if (files != null) {
                for (File file : files) {
                    addFileToZip(file, parentPath + fileToAdd.getName() + "/");
                }
            }
        } else {
            ZipEntry zipEntry = new ZipEntry(parentPath + fileToAdd.getName());
            currentZipOutputStream.putNextEntry(zipEntry);

            FileInputStream fis = new FileInputStream(fileToAdd);
            byte[] buffer = new byte[1024];
            int length;
            while ((length = fis.read(buffer)) >= 0) {
                currentZipOutputStream.write(buffer, 0, length);
                totalBytesWritten += length; // 更新已写入的总字节数
            }
            fis.close();
            currentZipOutputStream.closeEntry();
        }
    }

    private long getApproximateFileSize(File file) {
        if (file.isDirectory()) {
            long length = 0;
            File[] files = file.listFiles();
            if (files != null) {
                for (File childFile : files) {
                    length += getApproximateFileSize(childFile);
                }
            }
            return length;
        } else {
            return file.length();
        }
    }

    private void openNewZip() throws IOException {
        totalBytesWritten = 0; // 重置已写入的字节数
        currentZipCount++;
        currentZipFile = new File(outZipName + "_" + currentZipCount + ".zip");
        currentZipOutputStream = new ZipOutputStream(new FileOutputStream(currentZipFile));
    }

    private void closeCurrentZip() throws IOException {
        if (currentZipOutputStream != null) {
            currentZipOutputStream.close();
            currentZipOutputStream = null;
        }
    }

    public void zipDirectory(File directoryToZip, String baseDirectoryPath) throws IOException {
        basePath = baseDirectoryPath;
        if (directoryToZip.isDirectory()) {
            addFileToZip(directoryToZip, "");
        } else {
            throw new IOException("The specified path is not a directory.");
        }
        closeCurrentZip(); // 确保关闭最后一个ZIP文件  
    }

    /**
     *
     * @param folder 要压缩的文件夹
     * @param targetZipName 生成压缩包的名称
     */
    public void start(String folder,String targetZipName) throws Exception {
        if (isBlank(folder) || isBlank(targetZipName)) {
            throw new Exception("不能压缩。。。。。。");
        }
        outZipName = targetZipName;
        File dirToZip = new File(folder); // 替换为你要压缩的目录路径
        String baseDirPath = dirToZip.getName(); // 通常我们想要基于目录名来创建ZIP文件的根目录
        try {
            zipDirectory(dirToZip, baseDirPath + "/");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) throws Exception {
        SplitZip splitZip = new SplitZip();
        splitZip.start("D:\\新建文件夹","D:\\新建文件夹");
 } }

 




posted @ 2024-04-03 15:43  黄大虾  阅读(666)  评论(0编辑  收藏  举报