[By Peter Bromberg]
The .NET Framework has GzipStream and DeflateStream classes for compression tasks, but they do not support the standard ZIP file / folder FileEntry mechanism to zip a folder with all its files and subfolders.
Fortunately, the ICSharpCode SharpZipLib project does support this, as well as passwords for zip files and compression level.
Here is a utility class I wrote that handles zipping or unzipping a folder with all its subfolders and contained files, using SharpZipLib:
You can click Here to download the SharpZipLib!
1using System;
2using System.Collections;
3using System.IO;
4using ICSharpCode.SharpZipLib.Zip;
5
6namespace FolderZipper
7{
8 public static class ZipUtil
9 {
10 public static void ZipFiles(string inputFolderPath, string outputPathAndFile, string password)
11 {
12 ArrayList ar = GenerateFileList(inputFolderPath); // generate file list
13 int TrimLength = (Directory.GetParent(inputFolderPath)).ToString().Length;
14 // find number of chars to remove // from orginal file path
15 TrimLength += 1; //remove '\'
16 FileStream ostream;
17 byte[] obuffer;
18 string outPath = inputFolderPath + @"\" + outputPathAndFile;
19 ZipOutputStream oZipStream = new ZipOutputStream(File.Create(outPath)); // create zip stream
20 if (password != null && password != String.Empty)
21 oZipStream.Password = password;
22 oZipStream.SetLevel(9); // maximum compression
23 ZipEntry oZipEntry;
24 foreach (string Fil in ar) // for each file, generate a zipentry
25 {
26 oZipEntry = new ZipEntry(Fil.Remove(0, TrimLength));
27 oZipStream.PutNextEntry(oZipEntry);
28
29 if (!Fil.EndsWith(@"/")) // if a file ends with '/' its a directory
30 {
31 ostream = File.OpenRead(Fil);
32 obuffer = new byte[ostream.Length];
33 ostream.Read(obuffer, 0, obuffer.Length);
34 oZipStream.Write(obuffer, 0, obuffer.Length);
35 }
36 }
37 oZipStream.Finish();
38 oZipStream.Close();
39 }
40
41
42 private static ArrayList GenerateFileList(string Dir)
43 {
44 ArrayList fils = new ArrayList();
45 bool Empty = true;
46 foreach (string file in Directory.GetFiles(Dir)) // add each file in directory
47 {
48 fils.Add(file);
49 Empty = false;
50 }
51
52 if (Empty)
53 {
54 if (Directory.GetDirectories(Dir).Length == 0)
55 // if directory is completely empty, add it
56 {
57 fils.Add(Dir + @"/");
58 }
59 }
60
61 foreach (string dirs in Directory.GetDirectories(Dir)) // recursive
62 {
63 foreach (object obj in GenerateFileList(dirs))
64 {
65 fils.Add(obj);
66 }
67 }
68 return fils; // return file list
69 }
70
71
72 public static void UnZipFiles(string zipPathAndFile, string outputFolder, string password, bool deleteZipFile)
73 {
74 ZipInputStream s = new ZipInputStream(File.OpenRead(zipPathAndFile));
75 if (password != null && password != String.Empty)
76 s.Password = password;
77 ZipEntry theEntry;
78 string tmpEntry = String.Empty;
79 while ((theEntry = s.GetNextEntry()) != null)
80 {
81 string directoryName = outputFolder;
82 string fileName = Path.GetFileName(theEntry.Name);
83 // create directory
84 if (directoryName != "")
85 {
86 Directory.CreateDirectory(directoryName);
87 }
88 if (fileName != String.Empty)
89 {
90 if (theEntry.Name.IndexOf(".ini") < 0)
91 {
92 string fullPath = directoryName + "\\" + theEntry.Name;
93 fullPath = fullPath.Replace("\\ ", "\\");
94 string fullDirPath = Path.GetDirectoryName(fullPath);
95 if (!Directory.Exists(fullDirPath)) Directory.CreateDirectory(fullDirPath);
96 FileStream streamWriter = File.Create(fullPath);
97 int size = 2048;
98 byte[] data = new byte[2048];
99 while (true)
100 {
101 size = s.Read(data, 0, data.Length);
102 if (size > 0)
103 {
104 streamWriter.Write(data, 0, size);
105 }
106 else
107 {
108 break;
109 }
110 }
111 streamWriter.Close();
112 }
113 }
114 }
115 s.Close();
116 if (deleteZipFile)
117 File.Delete(zipPathAndFile);
118 }
119 }
120}