一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務(wù)器之家:專注于服務(wù)器技術(shù)及軟件下載分享
分類導(dǎo)航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術(shù)|正則表達(dá)式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務(wù)器之家 - 編程語言 - Java教程 - Java實(shí)現(xiàn)將文件或者文件夾壓縮成zip的詳細(xì)代碼

Java實(shí)現(xiàn)將文件或者文件夾壓縮成zip的詳細(xì)代碼

2022-03-08 00:46zeng1994 Java教程

這篇文章主要介紹了Java實(shí)現(xiàn)將文件或者文件夾壓縮成zip的詳細(xì)代碼,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下

最近碰到個需要下載zip壓縮包的需求,于是我在網(wǎng)上找了下別人寫好的zip工具類。但找了好多篇博客,總是發(fā)現(xiàn)有bug。因此就自己來寫了個工具類。
        這個工具類的功能為:
(1)可以壓縮文件,也可以壓縮文件夾
(2)同時支持壓縮多級文件夾,工具內(nèi)部做了遞歸處理
(3)碰到空的文件夾,也可以壓縮
(4)可以選擇是否保留原來的目錄結(jié)構(gòu),如果不保留,所有文件跑壓縮包根目錄去了,且空文件夾直接舍棄。注意:如果不保留文件原來目錄結(jié)構(gòu),在碰到文件名相同的文件時,會壓縮失敗。
(5)代碼中提供了2個壓縮文件的方法,一個的輸入?yún)?shù)為文件夾路徑,一個為文件列表,可根據(jù)實(shí)際需求選擇方法。

下面直接上代碼

一、代碼

?
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
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
package com.tax.core.util;
 
import java.io.File;
 
import java.io.FileInputStream;
 
import java.io.FileOutputStream;
 
import java.io.IOException;
 
import java.io.OutputStream;
 
import java.util.ArrayList;
 
import java.util.List;
 
import java.util.zip.ZipEntry;
 
import java.util.zip.ZipOutputStream;
 
/**
 
 * ZipUtils
 
 * @author  ZENG.XIAO.YAN
 
 * @date    2017年11月19日 下午7:16:08
 
 * @version v1.0
 
 */
 
public class ZipUtils {
 
    
 
    private static final int  BUFFER_SIZE = 2 * 1024;
 
    /**
 
     * 壓縮成ZIP 方法1
 
     * @param srcDir 壓縮文件夾路徑
 
     * @param out    壓縮文件輸出流
 
     * @param KeepDirStructure  是否保留原來的目錄結(jié)構(gòu),true:保留目錄結(jié)構(gòu);
 
     *                          false:所有文件跑到壓縮包根目錄下(注意:不保留目錄結(jié)構(gòu)可能會出現(xiàn)同名文件,會壓縮失敗)
 
     * @throws RuntimeException 壓縮失敗會拋出運(yùn)行時異常
 
     */
 
    public static void toZip(String srcDir, OutputStream out, boolean KeepDirStructure)
           throws RuntimeException{
 
        
 
        long start = System.currentTimeMillis();
 
        ZipOutputStream zos = null ;
 
        try {
 
            zos = new ZipOutputStream(out);
 
            File sourceFile = new File(srcDir);
 
            compress(sourceFile,zos,sourceFile.getName(),KeepDirStructure);
 
            long end = System.currentTimeMillis();
 
            System.out.println("壓縮完成,耗時:" + (end - start) +" ms");
 
        } catch (Exception e) {
 
            throw new RuntimeException("zip error from ZipUtils",e);
 
        }finally{
 
            if(zos != null){
 
                try {
 
                    zos.close();
 
                } catch (IOException e) {
 
                    e.printStackTrace();
 
                }
 
            }
 
        }
 
        
 
    }
 
    
 
    /**
 
     * 壓縮成ZIP 方法2
 
     * @param srcFiles 需要壓縮的文件列表
 
     * @param out           壓縮文件輸出流
 
     * @throws RuntimeException 壓縮失敗會拋出運(yùn)行時異常
 
     */
 
    public static void toZip(List<File> srcFiles , OutputStream out)throws RuntimeException {
 
        long start = System.currentTimeMillis();
 
        ZipOutputStream zos = null ;
 
        try {
 
            zos = new ZipOutputStream(out);
 
            for (File srcFile : srcFiles) {
 
                byte[] buf = new byte[BUFFER_SIZE];
 
                zos.putNextEntry(new ZipEntry(srcFile.getName()));
 
                int len;
 
                FileInputStream in = new FileInputStream(srcFile);
 
                while ((len = in.read(buf)) != -1){
 
                    zos.write(buf, 0, len);
 
                }
 
                zos.closeEntry();
 
                in.close();
 
            }
 
            long end = System.currentTimeMillis();
 
            System.out.println("壓縮完成,耗時:" + (end - start) +" ms");
 
        } catch (Exception e) {
 
            throw new RuntimeException("zip error from ZipUtils",e);
 
        }finally{
 
            if(zos != null){
 
                try {
 
                    zos.close();
 
                } catch (IOException e) {
 
                    e.printStackTrace();
 
                }
 
            }
 
        }
 
    }
 
    
 
    
 
    /**
 
     * 遞歸壓縮方法
 
     * @param sourceFile 源文件
 
     * @param zos        zip輸出流
 
     * @param name       壓縮后的名稱
 
     * @param KeepDirStructure  是否保留原來的目錄結(jié)構(gòu),true:保留目錄結(jié)構(gòu);
 
     *                          false:所有文件跑到壓縮包根目錄下(注意:不保留目錄結(jié)構(gòu)可能會出現(xiàn)同名文件,會壓縮失敗)
 
     * @throws Exception
 
     */
 
    private static void compress(File sourceFile, ZipOutputStream zos, String name,
 
            boolean KeepDirStructure) throws Exception{
 
        byte[] buf = new byte[BUFFER_SIZE];
 
        if(sourceFile.isFile()){
 
            // 向zip輸出流中添加一個zip實(shí)體,構(gòu)造器中name為zip實(shí)體的文件的名字
 
            zos.putNextEntry(new ZipEntry(name));
 
            // copy文件到zip輸出流中
 
            int len;
 
            FileInputStream in = new FileInputStream(sourceFile);
 
            while ((len = in.read(buf)) != -1){
 
                zos.write(buf, 0, len);
 
            }
 
            // Complete the entry
 
            zos.closeEntry();
 
            in.close();
 
        } else {
 
            File[] listFiles = sourceFile.listFiles();
 
            if(listFiles == null || listFiles.length == 0){
 
                // 需要保留原來的文件結(jié)構(gòu)時,需要對空文件夾進(jìn)行處理
 
                if(KeepDirStructure){
 
                    // 空文件夾的處理
 
                    zos.putNextEntry(new ZipEntry(name + "/"));
 
                    // 沒有文件,不需要文件的copy
 
                    zos.closeEntry();
 
                }
 
                
 
            }else {
 
                for (File file : listFiles) {
 
                    // 判斷是否需要保留原來的文件結(jié)構(gòu)
 
                    if (KeepDirStructure) {
 
                        // 注意:file.getName()前面需要帶上父文件夾的名字加一斜杠,
 
                        // 不然最后壓縮包中就不能保留原來的文件結(jié)構(gòu),即:所有文件都跑到壓縮包根目錄下了
 
                        compress(file, zos, name + "/" + file.getName(),KeepDirStructure);
 
                    } else {
 
                        compress(file, zos, file.getName(),KeepDirStructure);
 
                    }
 
                    
 
                }
 
            }
 
        }
 
    }
 
    public static void main(String[] args) throws Exception {
 
        /** 測試壓縮方法1  */
 
        FileOutputStream fos1 = new FileOutputStream(new File("c:/mytest01.zip"));
 
        ZipUtils.toZip("D:/log", fos1,true);
 
        /** 測試壓縮方法2  */
 
        List<File> fileList = new ArrayList<>();
 
        fileList.add(new File("D:/Java/jdk1.7.0_45_64bit/bin/jar.exe"));
 
        fileList.add(new File("D:/Java/jdk1.7.0_45_64bit/bin/java.exe"));
 
        FileOutputStream fos2 = new FileOutputStream(new File("c:/mytest02.zip"));
 
        ZipUtils.toZip(fileList, fos2);
 
    }
 
}

二、注意事項(xiàng)

寫該工具類時,有些注意事項(xiàng)說一下:
        (1)支持選擇是否保留原來的文件目錄結(jié)構(gòu),如果不保留,那么空文件夾直接不用處理。
        (1)碰到空文件夾時,如果需要保留目錄結(jié)構(gòu),則直接添加個ZipEntry就可以了,不過就是這個entry的名字后面需要帶上一斜杠(/)表示這個是目錄。
        (2)遞歸時,不需要把zip輸出流關(guān)閉,zip輸出流的關(guān)閉應(yīng)該是在調(diào)用完遞歸方法后面關(guān)閉
        (3)遞歸時,如果是個文件夾且需要保留目錄結(jié)構(gòu),那么在調(diào)用方法壓縮他的子文件時,需要把文件夾的名字加一斜杠給添加到子文件名字前面,這樣壓縮后才有多級目錄。

三、如何在javaWeb項(xiàng)目中使用該工具類

    這個工具類在web項(xiàng)目中的使用場景就是多文件下載,我就簡單說個下載多個excel表格的案例吧。
    代碼中的步驟為:
        (1)創(chuàng)建一個臨時文件夾
        (2)將要下載的文件生成至該臨時文件夾內(nèi)
        (3)當(dāng)所有文件生成完后,獲取HttpServletResponse獲取設(shè)置下載的header
        (4)調(diào)用工具類的方法,傳入上面生成的臨時文件夾路徑及response獲取的輸出流;這樣就下載出來zip包了
        (5)遞歸刪除掉上面生成的臨時文件夾和文件

    下面為一個示例代碼的代碼片段,不是完整代碼,簡單看一下代碼中的步驟

?
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
if(userList.size() > 0){
 
        /** 下面為下載zip壓縮包相關(guān)流程 */
 
        HttpServletRequest request = ServletActionContext.getRequest();
 
        FileWriter writer;
 
        /** 1.創(chuàng)建臨時文件夾  */
 
        String rootPath = request.getSession().getServletContext().getRealPath("/");
 
        File temDir = new File(rootPath + "/" + UUID.randomUUID().toString().replaceAll("-", ""));
 
        if(!temDir.exists()){
 
            temDir.mkdirs();
 
        }
 
        /** 2.生成需要下載的文件,存放在臨時文件夾內(nèi) */
 
        // 這里我們直接來10個內(nèi)容相同的文件為例,但這個10個文件名不可以相同
 
        for (int i = 0; i < 10; i++) {
 
            dataMap.put("userList", userList);
 
            Map<String, String> endMap = new HashMap<>();
 
            endMap.put("user", "老王");
 
            endMap.put("time", "2017-10-10 10:50:55");
 
            dataMap.put("endMap", endMap);
 
            Configuration cfg = new Configuration(Configuration.VERSION_2_3_22);
 
            cfg.setServletContextForTemplateLoading(ServletActionContext.getServletContext(), "/ftl");
 
            Template template = cfg.getTemplate("exportExcel.ftl");
 
            writer = new FileWriter(temDir.getPath()+"/excel"+ i +".xls");
 
            template.process(dataMap, writer);
 
            writer.flush();
 
            writer.close();
 
        }
 
        
 
        /** 3.設(shè)置response的header */
 
        HttpServletResponse response = ServletActionContext.getResponse();
 
        response.setContentType("application/zip");
 
        response.setHeader("Content-Disposition", "attachment; filename=excel.zip"); 
 
        /** 4.調(diào)用工具類,下載zip壓縮包 */
 
        // 這里我們不需要保留目錄結(jié)構(gòu)
 
        ZipUtils.toZip(temDir.getPath(), response.getOutputStream(),false);
 
   /** 5.刪除臨時文件和文件夾 */
 
        // 這里我沒寫遞歸,直接就這樣刪除了
 
        File[] listFiles = temDir.listFiles();
 
        for (int i = 0; i < listFiles.length; i++) {
 
            listFiles[i].delete();
 
        }
 
        temDir.delete();
 
    }

到此這篇關(guān)于Java實(shí)現(xiàn)將文件或者文件夾壓縮成zip的文章就介紹到這了,更多相關(guān)Java實(shí)現(xiàn)將文件或者文件夾壓縮成zip內(nèi)容請搜索服務(wù)器之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持服務(wù)器之家!

原文鏈接:https://www.cnblogs.com/zeng1994/p/7862288.html

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 久草热在线| 久久久乱码精品亚洲日韩 | 日老逼 | 日韩在线天堂免费观看 | 天堂成人在线视频 | 精品日韩二区三区精品视频 | 午夜一级| 2018高清国产一道国产 | 欧美成年黄网站色高清视频 | 美女被草出水 | 91禁漫| 深夜福利免费在线观看 | 亚洲 无码 制服 日韩 | 欧美ggg666 | 黑帮少爷爱上我第8集最新 荷兰精品女人性hd 和日本免费不卡在线v | 视频一区二区在线 | 91大神在线精品视频一区 | 国内精品久久久久久久久久久久 | 乌克兰一级片 | 免费看成年视频网页 | 国产日韩欧美综合在线 | 顶级欧美做受xxx000 | 羞羞视频免费观 | 91sao国产在线观看 | 亚洲va久久久久综合 | 国产中文在线视频 | 成人丁香婷婷 | 大胸纲手被羞羞漫画网站 | 精品一区二区高清在线观看 | 热久久免费视频 | 动漫女性扒开尿口羞羞漫画 | 九九精品热 | 日本在线小视频 | 狐媚小说 | 国产精品日韩欧美一区二区 | dasd817黑人在线播放 | 好男人影视社区www在线观看 | 精品午夜久久网成年网 | 99在线精品日韩一区免费国产 | 摸进老太婆的裤裆小说 | 欧美同性猛男videos |