rain
2024-05-20 4d1c72b10afcb0c4e7ba3b6caddd29b191ae5870
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
package com.dji.sample.patches.utils;
 
import com.amazonaws.util.IOUtils;
import org.springframework.context.annotation.Configuration;
 
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import java.util.zip.ZipOutputStream;
@Configuration
public class ZipUtil {
    /**
     * zip解压
     *
     * @param srcFile     zip源文件
     * @param destDirPath 解压后的目标文件夹
     * @return list 解压文件的路径合集
     * @throws RuntimeException 解压失败会抛出运行时异常
     */
    public static List<String> unZipFiles(File srcFile, String destDirPath) throws RuntimeException {
        List<String> list = new ArrayList<>();
        long start = System.currentTimeMillis();
        // 判断源文件是否存在
        if (!srcFile.exists()) {
            throw new RuntimeException(srcFile.getPath() + "所指文件不存在");
        }
        // 开始解压
        ZipFile zipFile = null;
        try {
            zipFile = new ZipFile(srcFile, Charset.forName("GBK"));
            Enumeration<?> entries = zipFile.entries();
            while (entries.hasMoreElements()) {
                ZipEntry entry = (ZipEntry) entries.nextElement();
 
                // 如果是文件夹,就创建个文件夹
                if (entry.isDirectory()) {
                    String dirPath = destDirPath + File.separator + entry.getName();
                    File dir = new File(dirPath);
                    dir.mkdirs();
                } else {
                    // 如果是文件,就先创建一个文件,然后用io流把内容copy过去
                    File targetFile = new File(destDirPath + File.separator + entry.getName());
                    // 保证这个文件的父文件夹必须要存在
 
                    list.add(destDirPath + entry.getName());
                    if (!targetFile.getParentFile().exists()) {
 
                    }
                    targetFile.createNewFile();
                    // 将压缩文件内容写入到这个文件中
                    InputStream is = zipFile.getInputStream(entry);
                    FileOutputStream fos = new FileOutputStream(targetFile);
                    int len;
                    byte[] buf = new byte[1024];
                    while ((len = is.read(buf)) != -1) {
                        fos.write(buf, 0, len);
                    }
                    // 关流顺序,先打开的后关闭
                    fos.close();
                    is.close();
                }
            }
            long end = System.currentTimeMillis();
 
        } catch (Exception e) {
            throw new RuntimeException("unzip error from ZipUtils", e);
        } finally {
            if (zipFile != null) {
                try {
                    zipFile.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return list;
    }
    // 定义一个公共的静态方法zipFolder,用于压缩文件夹
    // 参数sourceFolderPath是源文件夹的路径,zipFilePath是压缩后的zip文件路径
    public static boolean zipFolder(String sourceFolderPath, String zipFilePath) {
        // 创建一个File对象,表示源文件夹
        File sourceFile = new File(sourceFolderPath);
        try (
                // 创建一个FileOutputStream对象,用于向指定的zip文件路径写入数据
                FileOutputStream fos = new FileOutputStream(zipFilePath);
                // 创建一个ZipOutputStream对象,用于将压缩数据写入到FileOutputStream中
                ZipOutputStream zos = new ZipOutputStream(fos)
        ) {
            // 调用zipFile方法,开始压缩文件
            zipFile(sourceFile, sourceFile.getName(), zos);
            return true;
        } catch (IOException e) {
            // 如果在压缩过程中出现异常,打印异常堆栈信息
            e.printStackTrace();
        }
        return false;
    }
 
    // 将文件夹整体压缩
    // 参数fileToZip是需要被压缩的文件或文件夹,fileName是其在zip中的名称,zos是ZipOutputStream对象
    private static void zipFile(File fileToZip, String fileName, ZipOutputStream zos) throws IOException {
        // 如果fileToZip是一个隐藏文件,则不进行压缩,直接返回
        if (fileToZip.isHidden()) {
            return;
        }
        // 如果fileToZip是一个目录(文件夹)
        if (fileToZip.isDirectory()) {
            // 如果fileName以"/"结尾,说明已经是一个目录路径,直接创建一个ZipEntry并关闭它
            if (fileName.endsWith("/")) {
                zos.putNextEntry(new ZipEntry(fileName));
                zos.closeEntry();
            } else {
                // 否则,需要在fileName后加上"/",表示这是一个目录路径,然后创建一个ZipEntry并关闭它
                zos.putNextEntry(new ZipEntry(fileName + "/"));
                zos.closeEntry();
            }
            // 获取fileToZip目录下的所有文件和子目录
            File[] children = fileToZip.listFiles();
            for (File childFile : children) {
                // 递归调用zipFile方法,压缩子文件和子目录
                zipFile(childFile, fileName + "/" + childFile.getName(), zos);
            }
            return;
        }
        // 如果fileToZip不是一个目录,那么它就是一个文件,需要被压缩
        // 创建一个FileInputStream对象,用于读取fileToZip的内容
        FileInputStream fis = new FileInputStream(fileToZip);
        // 创建一个ZipEntry对象,表示fileToZip在zip文件中的条目
        ZipEntry zipEntry = new ZipEntry(fileName);
        // 在ZipOutputStream中开始一个新的zip条目(即将写入一个文件的内容)
        zos.putNextEntry(zipEntry);
        // 创建一个byte数组,作为缓冲区,用于从fileToZip读取数据并写入到zos中
        byte[] bytes = new byte[1024];
        int length;
        // 使用循环从fis中读取数据,并写入到zos中,直到没有数据可读(返回-1)为止
        while ((length = fis.read(bytes)) >= 0) {
            zos.write(bytes, 0, length);
        }
        // 关闭FileInputStream对象,释放资源
        fis.close();
    }
}