在项目对文件进行解压缩是非常常用的功能,对文件进行压缩存储或传输可以节省流量与空间。压缩文件的格式与方法都比较多,比较常用的国际标准是zip格式。压缩与解压缩的方法也很多,在.NET 2.0开始,在System.IO.Compression中微软已经给我们提供了解压缩的方法GZipStream。对于GZipStream的使用以及优缺点网上已经有非常多的文章,本文主要讲的是利用三方开源组件ICSharpCode.SharpZipLib进行文件的解压缩。
SharpZipLib地址:http://www.icsharpcode.net/OpenSource/SharpZipLib/Default.aspx
SharpZipLib是一个使用C#编写的Zip操作类库,是一个开源的C#压缩解压库,应用非常广泛。在VB.NET、C#或其他的.NET语言中都可以使用它创建Zip文件、并进行读取和更新等操作。SharpZipLib是一个完全由c#编写的Zip, GZip, Tar and BZip2 library,可以方便地支持这几种格式的压缩解压缩。SharpZipLib目前的版本为0.86,我们可以直接从上面提供的网站下载dll文件再添加到项目引用中,也可以通过VS提供的包管理工具NuGet把SharpZipLib添加到项目中。NuGet能更方便地把一些dll和文件添加到项目中,而不需要从文件中复制拷贝,推荐使用。使用NuGet添加SharpZipLib到项目中的方法如下图所示,在我们需要SharpZipLib的项目中右键单击“引用”,在弹出的快捷菜单中选择“管理NuGet程序包(N)…”。
在打开的“管理NuGet程序包”对话框,搜索SharpZipLib找到后单击安装即可。
引用SharpZipLib到项目中后,我们就可以编写相应的加压缩方法,下面将对常用的方法一一分享。
在使用前必须先添加引用如下:
1
2
|
using
ICSharpCode.SharpZipLib.Checksums;
using
ICSharpCode.SharpZipLib.Zip;
|
一、压缩文件夹
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
|
/// <summary>
/// 压缩文件夹
/// </summary>
/// <param name="dirToZip"></param>
/// <param name="zipedFileName"></param>
/// <param name="compressionLevel">压缩率0(无压缩)9(压缩率最高)</param>
public
static
void
ZipDir(
string
dirToZip,
string
zipedFileName,
int
compressionLevel = 9)
{
if
(Path.GetExtension(zipedFileName) !=
".zip"
)
{
zipedFileName = zipedFileName +
".zip"
;
}
using
(
var
zipoutputstream =
new
ZipOutputStream(File.Create(zipedFileName)))
{
zipoutputstream.SetLevel(compressionLevel);
Crc32 crc =
new
Crc32();
Hashtable fileList = GetAllFies(dirToZip);
foreach
(DictionaryEntry item
in
fileList)
{
FileStream fs =
new
FileStream(item.Key.ToString(), FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
byte
[] buffer =
new
byte
[fs.Length];
fs.Read(buffer, 0, buffer.Length);;
ZipEntry entry =
new
ZipEntry(Path.GetFileName(item.Key.ToString()))
{
DateTime = (DateTime)item.Value,
Size = fs.Length
};
fs.Close();
crc.Reset();
crc.Update(buffer);
entry.Crc = crc.Value;
zipoutputstream.PutNextEntry(entry);
zipoutputstream.Write(buffer, 0, buffer.Length);
}
}
}
|
二、解压文件夹
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
|
/// <summary>
/// 功能:解压zip格式的文件。
/// </summary>
/// <param name="zipFilePath">压缩文件路径</param>
/// <param name="unZipDir">解压文件存放路径,为空时默认与压缩文件同一级目录下,跟压缩文件同名的文件夹</param>
/// <returns>解压是否成功</returns>
public
static
void
UnZip(
string
zipFilePath,
string
unZipDir)
{
if
(zipFilePath ==
string
.Empty)
{
throw
new
Exception(
"压缩文件不能为空!"
);
}
if
(!File.Exists(zipFilePath))
{
throw
new
FileNotFoundException(
"压缩文件不存在!"
);
}
//解压文件夹为空时默认与压缩文件同一级目录下,跟压缩文件同名的文件夹
if
(unZipDir ==
string
.Empty)
unZipDir = zipFilePath.Replace(Path.GetFileName(zipFilePath), Path.GetFileNameWithoutExtension(zipFilePath));
if
(!unZipDir.EndsWith(
"/"
))
unZipDir +=
"/"
;
if
(!Directory.Exists(unZipDir))
Directory.CreateDirectory(unZipDir);
using
(
var
s =
new
ZipInputStream(File.OpenRead(zipFilePath)))
{
ZipEntry theEntry;
while
((theEntry = s.GetNextEntry()) !=
null
)
{
string
directoryName = Path.GetDirectoryName(theEntry.Name);
string
fileName = Path.GetFileName(theEntry.Name);
if
(!
string
.IsNullOrEmpty(directoryName))
{
Directory.CreateDirectory(unZipDir + directoryName);
}
if
(directoryName !=
null
&& !directoryName.EndsWith(
"/"
))
{
}
if
(fileName != String.Empty)
{
using
(FileStream streamWriter = File.Create(unZipDir + theEntry.Name))
{
int
size;
byte
[] data =
new
byte
[2048];
while
(
true
)
{
size = s.Read(data, 0, data.Length);
if
(size > 0)
{
streamWriter.Write(data, 0, size);
}
else
{
break
;
}
}
}
}
}
}
}
|
三、压缩单个文件
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
|
/// <summary>
/// 压缩单个文件
/// </summary>
/// <param name="fileToZip">要进行压缩的文件名,全路径</param>
/// <param name="zipedFile">压缩后生成的压缩文件名,全路径</param>
public
static
void
ZipFile(
string
fileToZip,
string
zipedFile)
{
// 如果文件没有找到,则报错
if
(!File.Exists(fileToZip))
{
throw
new
FileNotFoundException(
"指定要压缩的文件: "
+ fileToZip +
" 不存在!"
);
}
using
(FileStream fileStream = File.OpenRead(fileToZip))
{
byte
[] buffer =
new
byte
[fileStream.Length];
fileStream.Read(buffer, 0, buffer.Length);
fileStream.Close();
using
(FileStream zipFile = File.Create(zipedFile))
{
using
(ZipOutputStream zipOutputStream =
new
ZipOutputStream(zipFile))
{
// string fileName = fileToZip.Substring(fileToZip.LastIndexOf("\\") + 1);
string
fileName = Path.GetFileName(fileToZip);
var
zipEntry =
new
ZipEntry(fileName)
{
DateTime = DateTime.Now,
IsUnicodeText =
true
};
zipOutputStream.PutNextEntry(zipEntry);
zipOutputStream.SetLevel(5);
zipOutputStream.Write(buffer, 0, buffer.Length);
zipOutputStream.Finish();
zipOutputStream.Close();
}
}
}
}
|
三、压缩单个文件
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
|
/// <summary>
/// 压缩多个目录或文件
/// </summary>
/// <param name="folderOrFileList">待压缩的文件夹或者文件,全路径格式,是一个集合</param>
/// <param name="zipedFile">压缩后的文件名,全路径格式</param>
/// <param name="password">压宿密码</param>
/// <returns></returns>
public
static
bool
ZipManyFilesOrDictorys(IEnumerable<
string
> folderOrFileList,
string
zipedFile,
string
password)
{
bool
res =
true
;
using
(
var
s =
new
ZipOutputStream(File.Create(zipedFile)))
{
s.SetLevel(6);
if
(!
string
.IsNullOrEmpty(password))
{
s.Password = password;
}
foreach
(
string
fileOrDir
in
folderOrFileList)
{
//是文件夹
if
(Directory.Exists(fileOrDir))
{
res = ZipFileDictory(fileOrDir, s,
""
);
}
else
{
//文件
res = ZipFileWithStream(fileOrDir, s);
}
}
s.Finish();
s.Close();
return
res;
}
}
|
五、递归压缩文件夹
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
|
/// <summary>
/// 递归压缩文件夹方法
/// </summary>
/// <param name="folderToZip"></param>
/// <param name="s"></param>
/// <param name="parentFolderName"></param>
private
static
bool
ZipFileDictory(
string
folderToZip, ZipOutputStream s,
string
parentFolderName)
{
bool
res =
true
;
ZipEntry entry =
null
;
FileStream fs =
null
;
Crc32 crc =
new
Crc32();
try
{
//创建当前文件夹
entry =
new
ZipEntry(Path.Combine(parentFolderName, Path.GetFileName(folderToZip) +
"/"
));
//加上 “/” 才会当成是文件夹创建
s.PutNextEntry(entry);
s.Flush();
//先压缩文件,再递归压缩文件夹
var
filenames = Directory.GetFiles(folderToZip);
foreach
(
string
file
in
filenames)
{
//打开压缩文件
fs = File.OpenRead(file);
byte
[] buffer =
new
byte
[fs.Length];
fs.Read(buffer, 0, buffer.Length);
entry =
new
ZipEntry(Path.Combine(parentFolderName, Path.GetFileName(folderToZip) +
"/"
+ Path.GetFileName(file)));
entry.DateTime = DateTime.Now;
entry.Size = fs.Length;
fs.Close();
crc.Reset();
crc.Update(buffer);
entry.Crc = crc.Value;
s.PutNextEntry(entry);
s.Write(buffer, 0, buffer.Length);
}
}
catch
{
res =
false
;
}
finally
{
if
(fs !=
null
)
{
fs.Close();
}
if
(entry !=
null
)
{
}
GC.Collect();
GC.Collect(1);
}
var
folders = Directory.GetDirectories(folderToZip);
foreach
(
string
folder
in
folders)
{
if
(!ZipFileDictory(folder, s, Path.Combine(parentFolderName, Path.GetFileName(folderToZip))))
{
return
false
;
}
}
return
res;
}
|
利用ICSharpCode.SharpZipLib解压缩辅助类全部代码如下:
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
|