参考
https://blog.csdn.net/lki_suidongdong/article/details/20942977
重点:
实现多级子目录的压缩,类似winrar,可以选择是否排除基准目录
1
public
void ZipDirectoryTest()
2
{
3
string path = System.IO.Path.Combine(System.IO.Path.GetTempPath(), DateTime.Now.Ticks.ToString());
4
foreach (string sub in
new
string[] { "bin", "release", "test", "test\\bin", "" })
5
{
6
string subPath = System.IO.Path.Combine(path, sub);
7
if (!System.IO.Directory.Exists(subPath))
8
System.IO.Directory.CreateDirectory(subPath);
9 System.IO.File.WriteAllText(System.IO.Path.Combine(subPath, "1.cs"), "");
10 System.IO.File.WriteAllText(System.IO.Path.Combine(subPath, "1.txt"), "");
11 System.IO.File.WriteAllText(System.IO.Path.Combine(subPath, "1.html"), "");
12 System.IO.File.WriteAllText(System.IO.Path.Combine(subPath, "1.bin"), "");
13
14
}
15
Console.WriteLine(path);
16
17
new ZipHelper().ZipDirectory(path, "e:\\temp\\tt.zip",false);
18 ZipHelper.UnZip("e:\\temp\\tt.zip", "e:\\temp\\tt2");
19
//System.IO.Directory.Delete(path, true);
20
//Q.Helper.FileHelper.SelectFile(path);
21 }
代码
1
using System;
2
3
using System.Collections.Generic;
4
5
using System.Linq;
6
7
using System.Text;
8
9
using System.IO;
10
11
using ICSharpCode.SharpZipLib;
12
13
using ICSharpCode.SharpZipLib.Zip;
14
15
#if NETSTANDARD2_0
16
17
using ICSharpCode.SharpZipLib.Checksum;
18
19
#else
20
21
using ICSharpCode.SharpZipLib.Checksums;
22
23
#endif
24
25
26
27
namespace Q.Helper.Zip
28
29
{
30
31
32
33
///
<summary>
34
35
/// 适用与ZIP压缩
36
37
///
</summary>
38
39
public
class ZipHelper
40
41
{
42
43
public
int Level
44
45
{
46
47
get; set;
48
49
}
50
51
#region 压缩
52
53
54
55
///
<summary>
56
57
/// 递归压缩文件夹的内部方法(排除相对路径)
58
59
///
</summary>
60
61
///
<param name="folderToZip">要压缩的文件夹路径</param>
62
63
///
<param name="zipStream">压缩输出流</param>
64
65
///
<param name="parentFolderName">此文件夹的上级文件夹</param>
66
67
///
<param name="includeFloderName">是否包含目录名</param>
68
69
///
<returns></returns>
70
71
private
bool ZipDirectory(string folderToZip, ZipOutputStream zipStream, string parentFolderName, bool createBaseFolder = true)
72
73
{
74
75 folderToZip = folderToZip.Replace("\\", "/");
76
77
bool result = true;
78
79
string[] folders, files;
80
81 ZipEntry ent = null;
82
83 FileStream fs = null;
84
85 Crc32 crc = new Crc32();
86
87
88
89
try
90
91
{
92
93
string entPath = Path.Combine(parentFolderName, Path.GetFileName(folderToZip) + "/").Replace("\\", "/");
94
95
if (!createBaseFolder)
96
97 entPath = entPath.Substring(entPath.IndexOf("/") + 1);
98
99
if (!string.IsNullOrEmpty(entPath))
100
101
{
102
103 ent = new ZipEntry(entPath);
104
105
Console.WriteLine(entPath);
106
107
zipStream.PutNextEntry(ent);
108
109
zipStream.Flush();
110
111
}
112
113 files = Directory.GetFiles(folderToZip);
114
115
foreach (string file in files)
116
117
{
118
119 fs = File.OpenRead(file);
120
121
122
123
byte[] buffer = new
byte[fs.Length];
124
125 fs.Read(buffer, 0, buffer.Length);
126
127 entPath = Path.Combine(parentFolderName, Path.GetFileName(folderToZip) + "/" + Path.GetFileName(file)).Replace("\\", "/");
128
129
if (!createBaseFolder)
130
131 entPath = entPath.Substring(entPath.IndexOf("/") + 1);
132
133
Console.WriteLine(entPath);
134
135 ent = new ZipEntry(entPath);
136
137 ent.DateTime = DateTime.Now;
138
139 ent.Size = fs.Length;
140
141
142
143
fs.Close();
144
145
146
147
crc.Reset();
148
149
crc.Update(buffer);
150
151
152
153 ent.Crc = crc.Value;
154
155
zipStream.PutNextEntry(ent);
156
157 zipStream.Write(buffer, 0, buffer.Length);
158
159
}
160
161
162
163
}
164
165
catch (Exception ex)
166
167
{
168
169 result = false;
170
171
throw ex;
172
173
}
174
175
finally
176
177
{
178
179
if (fs != null)
180
181
{
182
183
fs.Close();
184
185
fs.Dispose();
186
187
}
188
189
if (ent != null)
190
191
{
192
193 ent = null;
194
195
}
196
197
GC.Collect();
198
199 GC.Collect(1);
200
201
}
202
203
204
205 folders = Directory.GetDirectories(folderToZip);
206
207
//多级递归时需要记住相对目录
208
209
foreach (string folder in folders)
210
211
{
212
213
if (!ZipDirectory(folder, zipStream, Path.Combine(parentFolderName, Path.GetFileName(folderToZip)), createBaseFolder))
214
215
return
false;
216
217
}
218
219
return result;
220
221
}
222
223
224
225
///
<summary>
226
227
/// 压缩文件夹
228
229
///
</summary>
230
231
///
<param name="folderToZip">要压缩的文件夹路径</param>
232
233
///
<param name="zipedFile">压缩文件完整路径</param>
234
235
///
<param name="password">密码</param>
236
237
///
<returns>是否压缩成功</returns>
238
239
public
bool ZipDirectory(string folderToZip, string zipedFile, string password, bool includeFloderName = true)
240
241
{
242
243
bool result = false;
244
245
if (!Directory.Exists(folderToZip))
246
247
return result;
248
249
250
251 ZipOutputStream zipStream = new ZipOutputStream(File.Create(zipedFile));
252
253
zipStream.SetLevel(Level);
254
255
if (!string.IsNullOrEmpty(password)) zipStream.Password = password;
256
257
258
259 result = ZipDirectory(folderToZip, zipStream, "", includeFloderName);
260
261
262
263
zipStream.Finish();
264
265
zipStream.Close();
266
267
268
269
return result;
270
271
}
272
273
274
275
///
<summary>
276
277
/// 压缩文件夹
278
279
///
</summary>
280
281
///
<param name="folderToZip">要压缩的文件夹路径</param>
282
283
///
<param name="zipedFile">压缩文件完整路径</param>
284
285
///
<returns>是否压缩成功</returns>
286
287
public
bool ZipDirectory(string folderToZip, string zipedFile, bool includeFloderName = true)
288
289
{
290
291
bool result = ZipDirectory(folderToZip, zipedFile, "", includeFloderName);
292
293
return result;
294
295
}
296
297
298
299
///
<summary>
300
301
/// 压缩文件
302
303
///
</summary>
304
305
///
<param name="fileToZip">要压缩的文件全名</param>
306
307
///
<param name="zipedFile">压缩后的文件名</param>
308
309
///
<param name="password">密码</param>
310
311
///
<returns>压缩结果</returns>
312
313
public
bool ZipFile(string fileToZip, string zipedFile, string password)
314
315
{
316
317
bool result = true;
318
319 ZipOutputStream zipStream = null;
320
321 FileStream fs = null;
322
323 ZipEntry ent = null;
324
325
326
327
if (!File.Exists(fileToZip))
328
329
return
false;
330
331
332
333
try
334
335
{
336
337 fs = File.OpenRead(fileToZip);
338
339
byte[] buffer = new
byte[fs.Length];
340
341 fs.Read(buffer, 0, buffer.Length);
342
343
fs.Close();
344
345
346
347 fs = File.Create(zipedFile);
348
349 zipStream = new ZipOutputStream(fs);
350
351
if (!string.IsNullOrEmpty(password)) zipStream.Password = password;
352
353 ent = new ZipEntry(Path.GetFileName(fileToZip));
354
355
zipStream.PutNextEntry(ent);
356
357
zipStream.SetLevel(Level);
358
359
360
361 zipStream.Write(buffer, 0, buffer.Length);
362
363
364
365
}
366
367
catch
368
369
{
370
371 result = false;
372
373
}
374
375
finally
376
377
{
378
379
if (zipStream != null)
380
381
{
382
383
zipStream.Finish();
384
385
zipStream.Close();
386
387
}
388
389
if (ent != null)
390
391
{
392
393 ent = null;
394
395
}
396
397
if (fs != null)
398
399
{
400
401
fs.Close();
402
403
fs.Dispose();
404
405
}
406
407
}
408
409
GC.Collect();
410
411 GC.Collect(1);
412
413
414
415
return result;
416
417
}
418
419
420
421
///
<summary>
422
423
/// 压缩文件
424
425
///
</summary>
426
427
///
<param name="fileToZip">要压缩的文件全名</param>
428
429
///
<param name="zipedFile">压缩后的文件名</param>
430
431
///
<returns>压缩结果</returns>
432
433
public
bool ZipFile(string fileToZip, string zipedFile)
434
435
{
436
437
bool result = ZipFile(fileToZip, zipedFile, null);
438
439
return result;
440
441
}
442
443
444
445
///
<summary>
446
447
/// 压缩文件或文件夹
448
449
///
</summary>
450
451
///
<param name="fileToZip">要压缩的路径</param>
452
453
///
<param name="zipedFile">压缩后的文件名</param>
454
455
///
<param name="password">密码</param>
456
457
///
<returns>压缩结果</returns>
458
459
public
bool Zip(string fileToZip, string zipedFile, string password)
460
461
{
462
463
bool result = false;
464
465
if (Directory.Exists(fileToZip))
466
467 result = ZipDirectory(fileToZip, zipedFile, password);
468
469
else
if (File.Exists(fileToZip))
470
471 result = ZipFile(fileToZip, zipedFile, password);
472
473
474
475
return result;
476
477
}
478
479
480
481
///
<summary>
482
483
/// 压缩文件或文件夹
484
485
///
</summary>
486
487
///
<param name="fileToZip">要压缩的路径</param>
488
489
///
<param name="zipedFile">压缩后的文件名</param>
490
491
///
<returns>压缩结果</returns>
492
493
public
bool Zip(string fileToZip, string zipedFile)
494
495
{
496
497
bool result = Zip(fileToZip, zipedFile, null);
498
499
return result;
500
501
502
503
}
504
505
506
507
#endregion
508
509
510
511
#region 解压
512
513
514
515
///
<summary>
516
517
/// 解压功能(解压压缩文件到指定目录)
518
519
///
</summary>
520
521
///
<param name="fileToUnZip">待解压的文件</param>
522
523
///
<param name="zipedFolder">指定解压目标目录</param>
524
525
///
<param name="password">密码</param>
526
527
///
<returns>解压结果</returns>
528
529
public
static
bool UnZip(string fileToUnZip, string zipedFolder, string password)
530
531
{
532
533
bool result = true;
534
535
536
537 ZipInputStream zipStream = null;
538
539 ZipEntry ent = null;
540
541
string fileName;
542
543
544
545
if (!File.Exists(fileToUnZip))
546
547
return
false;
548
549
550
551
if (!Directory.Exists(zipedFolder))
552
553
Directory.CreateDirectory(zipedFolder);
554
555
556
557
try
558
559
{
560
561 zipStream = new ZipInputStream(File.OpenRead(fileToUnZip));
562
563
if (!string.IsNullOrEmpty(password)) zipStream.Password = password;
564
565
while ((ent = zipStream.GetNextEntry()) != null)
566
567
{
568
569
if (!string.IsNullOrEmpty(ent.Name))
570
571
{
572
573 fileName = Path.Combine(zipedFolder, ent.Name);
574
575 fileName = fileName.Replace('/', '\\');//change by Mr.HopeGi
576
577
578
579
if (fileName.EndsWith("\\"))
580
581
{
582
583
Directory.CreateDirectory(fileName);
584
585
continue;
586
587
}
588
589
using (FileStream fs = File.Create(fileName))
590
591
{
592
593
int size = 2048;
594
595
byte[] data = new
byte[size];
596
597
while (true)
598
599
{
600
601
602
603 size = zipStream.Read(data, 0, data.Length);
604
605
if (size > 0)
606
607 fs.Write(data, 0, data.Length);
608
609
else
610
611
break;
612
613
}
614
615
fs.Flush();
616
617
618
619
fs.Close();
620
621
new FileInfo(fileName).LastWriteTime = ent.DateTime;
622
623
}
624
625
626
627
}
628
629
}
630
631
}
632
633
catch
634
635
{
636
637 result = false;
638
639
}
640
641
finally
642
643
{
644
645
646
647
if (zipStream != null)
648
649
{
650
651
zipStream.Close();
652
653
zipStream.Dispose();
654
655
}
656
657
if (ent != null)
658
659
{
660
661 ent = null;
662
663
}
664
665
GC.Collect();
666
667 GC.Collect(1);
668
669
}
670
671
return result;
672
673
}
674
675
676
677
///
<summary>
678
679
/// 解压功能(解压压缩文件到指定目录)
680
681
///
</summary>
682
683
///
<param name="fileToUnZip">待解压的文件</param>
684
685
///
<param name="zipedFolder">指定解压目标目录</param>
686
687
///
<returns>解压结果</returns>
688
689
public
static
bool UnZip(string fileToUnZip, string zipedFolder)
690
691
{
692
693
bool result = UnZip(fileToUnZip, zipedFolder, null);
694
695
return result;
696
697
}
698
699
700
701
#endregion
702
703
}
704
705 }