https://www.cnblogs.com/kissdodog/p/3525295.html
一、ZipFile
ZipFile類用於選擇文件或文件夾進行壓縮生成壓縮包。
常用屬性:
屬性
說明
Count
文件數目(注意是在ComitUpdat之后才有)
Password
壓縮包密碼
Size
壓縮包占用空間大小
Name
壓縮包名稱,默認輸出是文件路徑
ZipEntry
壓縮包里的文件,通過索引[]訪問
其常用方法如下:
方法
說明
Add
添加要進行壓縮的文件
AddDirectory
添加文件夾(不會壓縮文件夾里的文件)
Delete
刪除文件或文件夾
BeginUpdate
開始修改壓縮包
CommitUpdate
提交修改
SetComment
添加注釋
示例1(創建壓縮文件):
using (ZipFile zip = ZipFile.Create(@"D:\test.zip"))
{
zip.BeginUpdate();
zip.SetComment("這是我的壓縮包");
zip.Add(@"D:\1.txt"); //添加一個文件
zip.AddDirectory(@"D:\2"); //添加一個文件夾(這個方法不會壓縮文件夾里的文件)
zip.Add(@"D:\2\2.txt"); //添加文件夾里的文件
zip.CommitUpdate();
}
這樣生成的壓縮包是包含子文件夾,子文件夾也是包含子文件的。
其中,注釋如下:

示例2:修改壓縮包
using (ZipFile zip = new ZipFile(@"D:\test.zip"))
{
zip.BeginUpdate();
zip.Add(@"D:\2.txt");
zip.CommitUpdate();
}
留意這個示例和上面的有什么不同,上面的是Create方法創建的ZipFile對象,而這里是直接讀。因此,如果壓縮包里面有文件,則不會改動原來的壓縮文件,而是往會里面添加一個。這樣就相當於壓縮包的修改,而上面是壓縮包的創建。
示例3:讀取壓縮包里的文件:
using (ZipFile zip = new ZipFile(@"D:\test.zip"))
{
foreach (ZipEntry z in zip)
{
Console.WriteLine(z);
}
ZipEntry z1 = zip[0];
Console.WriteLine(z1.Name);
}
二、FastZip
這個類就兩個方法:
方法
說明
CreateZip
壓縮目錄
ExtractZip
解壓縮目錄
1、FastZip用於快速壓縮目錄,示例如下:
//快速壓縮目錄,包括目錄下的所有文件 (new FastZip()).CreateZip(@"D:\test.zip", @"D:\test\", true, "");
這個是遞歸壓縮的。但是局限性就是只能壓縮文件夾。
否則報如下錯誤:

2、快速解壓縮目錄
//快速解壓 (new FastZip()).ExtractZip(@"D:\test.zip", @"D:\解壓目錄\", "");
三、ZipOutputStream與ZipEntry
- ZipOutputStream:相當於一個壓縮包;
- ZipEntry:相當於壓縮包里的一個文件;
以上兩個類是SharpZipLib的主類,最耐玩的就是這兩個類。
ZipOutputStream常用屬性:
屬性
說明
IsFinished
ZipOutputStream是否已結束
ZipOutputStream常用方法:
方法
說明
CloseEntry
關閉入口,關閉之后不允許再對ZipOutputStream進行操作
Finish
結束寫入
GetLevel
讀取壓縮等級
PutNextEntry
往ZipOutputStream里寫入一個ZipEntry
SetComment
壓縮包的注釋
SetLevel
設置壓縮等級,等級越高文件越小
Write
寫入文件內容
使用ZipOutputStream創建一個壓縮包並往里面寫入一個文件的示例:
static void Main(string[] args)
{
using (ZipOutputStream s = new ZipOutputStream(File.Create(@"D:\123.zip")))
{
s.SetLevel(6); //設置壓縮等級,等級越高壓縮效果越明顯,但占用CPU也會更多using (FileStream fs = File.OpenRead(@"D:\1.txt"))
{
byte[] buffer = new byte[4 * 1024]; //緩沖區,每次操作大小
ZipEntry entry = new ZipEntry(Path.GetFileName(@"改名.txt")); //創建壓縮包內的文件
entry.DateTime = DateTime.Now; //文件創建時間
s.PutNextEntry(entry); //將文件寫入壓縮包
int sourceBytes;
do
{
sourceBytes = fs.Read(buffer, 0, buffer.Length); //讀取文件內容(1次讀4M,寫4M)
s.Write(buffer, 0, sourceBytes); //將文件內容寫入壓縮相應的文件
} while (sourceBytes > 0);
}
s.CloseEntry();
}
Console.ReadKey();
}
以上示例僅僅能夠壓縮文件,要壓縮文件夾就要使用遞歸的方式,循環子目錄並壓縮子目錄里的文件。
示例2:文件夾壓縮,保持原文件夾架構:
class Program
{
static void Main(string[] args)
{
string Source = @"D:\test";
string TartgetFile = @"D:\test.zip";
Directory.CreateDirectory(Path.GetDirectoryName(TartgetFile));
using (ZipOutputStream s = new ZipOutputStream(File.Create(TartgetFile)))
{
s.SetLevel(6);
Compress(Source, s);
s.Finish();
s.Close();
}
Console.ReadKey();
}
/// <summary>
/// 壓縮
/// </summary>
/// <param name="source">源目錄</param>
/// <param name="s">ZipOutputStream對象</param>
public static void Compress(string source, ZipOutputStream s)
{
string[] filenames = Directory.GetFileSystemEntries(source);
foreach (string file in filenames)
{
if (Directory.Exists(file))
{
Compress(file, s); //遞歸壓縮子文件夾
}
else
{
using (FileStream fs = File.OpenRead(file))
{
byte[] buffer = new byte[4 * 1024];
ZipEntry entry = new ZipEntry(file.Replace(Path.GetPathRoot(file),"")); //此處去掉盤符,如D:\123\1.txt 去掉D:
entry.DateTime = DateTime.Now;
s.PutNextEntry(entry);
int sourceBytes;
do
{
sourceBytes = fs.Read(buffer, 0, buffer.Length);
s.Write(buffer, 0, sourceBytes);
} while (sourceBytes > 0);
}
}
}
}
}
附上解壓縮方法:
/// <summary>
/// 解壓縮
/// </summary>
/// <param name="sourceFile">源文件</param>
/// <param name="targetPath">目標路經</param>
public bool Decompress(string sourceFile, string targetPath)
{
if (!File.Exists(sourceFile))
{
throw new FileNotFoundException(string.Format("未能找到文件 '{0}' ", sourceFile));
}
if (!Directory.Exists(targetPath))
{
Directory.CreateDirectory(targetPath);
}
using (ZipInputStream s = new ZipInputStream(File.OpenRead(sourceFile)))
{
ZipEntry theEntry;
while ((theEntry = s.GetNextEntry()) != null)
{
string directorName = Path.Combine(targetPath, Path.GetDirectoryName(theEntry.Name));
string fileName = Path.Combine(directorName, Path.GetFileName(theEntry.Name));
// 創建目錄
if (directorName.Length > 0)
{
Directory.CreateDirectory(directorName);
}
if (fileName != string.Empty)
{
using (FileStream streamWriter = File.Create(fileName))
{
int size = 4096;
byte[] data = new byte[ 4 * 1024];
while (true)
{
size = s.Read(data, 0, data.Length);
if (size > 0)
{
streamWriter.Write(data, 0, size);
}
else break;
}
}
}
}
}
return true;
}

