- ubuntu12.04环境下使用kvm ioctl接口实现最简单的虚拟机
- Ubuntu 通过无线网络安装Ubuntu Server启动系统后连接无线网络的方法
- 在Ubuntu上搭建网桥的方法
- ubuntu 虚拟机上网方式及相关配置详解
CFSDN坚持开源创造价值,我们致力于搭建一个资源共享平台,让每一个IT人在这里找到属于你的精彩世界.
这篇CFSDN的博客文章详解最好的.NET开源免费ZIP库DotNetZip(.NET组件介绍之三)由作者收集整理,如果你对这篇文章有兴趣,记得点赞哟.
在项目开发中,除了对数据的展示更多的就是对文件的相关操作,例如文件的创建和删除,以及文件的压缩和解压。文件压缩的好处有很多,主要就是在文件传输的方面,文件压缩的好处就不需要赘述,因为无论是开发者,还是使用者对于文件压缩的好处都是深有体会。至于文件压缩的原理,在我的另一篇博客中有简单的介绍,在这里就不再做介绍,需要了解的可以查看.
.NET在System.IO.Compression命名空间中提供了GZip、Defalate两种压缩算法。今天我要介绍的一种压缩组件是DotNetZip组件.
一.DotNetZip组件概述:
在DotNetZip的自我介绍中号称是”DotNetZip是.NET最好的开源ZIP库“,至于是不是最好的压缩组件,在这里就不做评价,毕竟每个使用者的心态和工作环境不同,项目对组件的需求也不同,在选择组件的时候,就需要开发者自己衡量了。估计很多人还没有看到这里就开始在键盘上敲字吐槽了,标题是我借用官方对外的宣传口号,不用太在意这些细节.
DotNetZip - Zip和解压缩在C#,VB,任何.NET语言都可使用。DotNetZip是一个FAST,免费类库和用于操纵zip文件的工具集。 使用VB,C#或任何.NET语言轻松创建,解压缩或更新zip文件。DotNetZip在具有完整.NET Framework的PC上运行,并且还在使用.NET Compact Framework的移动设备上运行。在VB,C#或任何.NET语言或任何脚本环境中创建和读取zip文件.
DotNetZip组件的使用环境,毕竟软件的使用环境是每一个开发者都需要考虑的,这个世界没有绝对的好事,当然也没有绝对的坏事。接下来看一下其实用环境的说明吧:
1.一个动态创建zip文件的Silverlight应用程序.
2.一个ASP.NET应用程序,动态创建ZIP文件并允许浏览器下载它们.
3.一个Windows服务,定期地为了备份和归档目的上拉一个目录.
4.修改现有归档的WPF程序 - 重命名条目,从归档中删除条目或向归档中添加新条目.
5.一个Windows窗体应用程序,用于为归档内容的隐私创建AES加密的zip存档.
6.解压缩或拉链的SSIS脚本.
7.PowerShell或VBScript中的一个管理脚本,用于执行备份和归档.
8.WCF服务,接收作为附件的zip文件,并动态地将zip解压缩到流以进行分析.
9.一个老式的ASP(VBScript)应用程序,通过COM接口为DotNetZIp生成一个ZIP文件.
10.读取或更新ODS文件的Windows Forms应用程序.
11.从流内容创建zip文件,保存到流,提取到流,从流读取.
12.创建自解压档案.
DotNetZip是一个100%的托管代码库,可用于任何.NET应用程序 - 控制台,Winforms,WPF,ASP.NET,Sharepoint,Web服务应用程序等。 新的v1.9.1.6:Silverlight。 它还可以从脚本环境或具有COM功能的环境(如Powershell脚本,VBScript,VBA,VB6,PHP,Perl,Javascript等)中使用。 无论使用什么环境,DotNetZip生成的zip文件可与Windows资源管理器以及Java应用程序,在Linux上运行的应用程序完全互操作.
该组件设计简单,易于使用。 DotNetZip打包为一个单一的DLL,大小约400k。 它没有第三方依赖。 它是中等信任,因此可以在大多数托管商使用。 通过引用DLL来获取压缩。 该库支持zip密码,Unicode,ZIP64,流输入和输出,AES加密,多个压缩级别,自解压缩存档,跨区存档等.
以上的一些描述来自与官网,就不再吹捧这个组件了,在这里需要说明的是在组件的选择和使用上,主要取决与项目的实际情况。详情见:http://dotnetzip.codeplex.com/ 。
二.DotNetZip相关核心类和方法解析:
由于下载的是DLL文件,还是采用.NET Reflector对DLL文件进行反编译,以此查看源代码。一下主要介绍一些类和方法,没有完全介绍,首先是由于篇幅所限,其实是完全没有必要,因为对于开发者而言,没有必要全部了解这些类,在实际的开发中,可以根据API进行对应的方法调用,这些技能应该是一个开发人员应该具备的.
1.ZipFile类的AddEntry()、Save()和IsZipFile()方法:
1
2
3
4
5
6
7
8
9
|
public
ZipEntry AddEntry(
string
entryName, WriteDelegate writer)
{
ZipEntry ze = ZipEntry.CreateForWriter(entryName, writer);
if
(
this
.Verbose)
{
this
.StatusMessageTextWriter.WriteLine(
"adding {0}..."
, entryName);
}
return
this
._InternalAddEntry(ze);
}
|
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
|
public
void
Save()
{
try
{
bool
flag =
false
;
this
._saveOperationCanceled =
false
;
this
._numberOfSegmentsForMostRecentSave = 0;
this
.OnSaveStarted();
if
(
this
.WriteStream ==
null
)
{
throw
new
BadStateException(
"You haven't specified where to save the zip."
);
}
if
(((
this
._name !=
null
) &&
this
._name.EndsWith(
".exe"
)) && !
this
._SavingSfx)
{
throw
new
BadStateException(
"You specified an EXE for a plain zip file."
);
}
if
(!
this
._contentsChanged)
{
this
.OnSaveCompleted();
if
(
this
.Verbose)
{
this
.StatusMessageTextWriter.WriteLine(
"No save is necessary...."
);
}
}
else
{
this
.Reset(
true
);
if
(
this
.Verbose)
{
this
.StatusMessageTextWriter.WriteLine(
"saving...."
);
}
if
((
this
._entries.Count >= 0xffff) && (
this
._zip64 == Zip64Option.Default))
{
throw
new
ZipException(
"The number of entries is 65535 or greater. Consider setting the UseZip64WhenSaving property on the ZipFile instance."
);
}
int
current = 0;
ICollection<ZipEntry> entries =
this
.SortEntriesBeforeSaving ?
this
.EntriesSorted :
this
.Entries;
foreach
(ZipEntry entry
in
entries)
{
this
.OnSaveEntry(current, entry,
true
);
entry.Write(
this
.WriteStream);
if
(
this
._saveOperationCanceled)
{
break
;
}
current++;
this
.OnSaveEntry(current, entry,
false
);
if
(
this
._saveOperationCanceled)
{
break
;
}
if
(entry.IncludedInMostRecentSave)
{
flag |= entry.OutputUsedZip64.Value;
}
}
if
(!
this
._saveOperationCanceled)
{
ZipSegmentedStream writeStream =
this
.WriteStream
as
ZipSegmentedStream;
this
._numberOfSegmentsForMostRecentSave = (writeStream !=
null
) ? writeStream.CurrentSegment : 1;
bool
flag2 = ZipOutput.WriteCentralDirectoryStructure(
this
.WriteStream, entries,
this
._numberOfSegmentsForMostRecentSave,
this
._zip64,
this
.Comment,
new
ZipContainer(
this
));
this
.OnSaveEvent(ZipProgressEventType.Saving_AfterSaveTempArchive);
this
._hasBeenSaved =
true
;
this
._contentsChanged =
false
;
flag |= flag2;
this
._OutputUsesZip64 =
new
bool
?(flag);
if
((
this
._name !=
null
) && ((
this
._temporaryFileName !=
null
) || (writeStream !=
null
)))
{
this
.WriteStream.Dispose();
if
(
this
._saveOperationCanceled)
{
return
;
}
if
(
this
._fileAlreadyExists && (
this
._readstream !=
null
))
{
this
._readstream.Close();
this
._readstream =
null
;
foreach
(ZipEntry entry2
in
entries)
{
ZipSegmentedStream stream2 = entry2._archiveStream
as
ZipSegmentedStream;
if
(stream2 !=
null
)
{
stream2.Dispose();
}
entry2._archiveStream =
null
;
}
}
string
path =
null
;
if
(File.Exists(
this
._name))
{
path =
this
._name +
"."
+ Path.GetRandomFileName();
if
(File.Exists(path))
{
this
.DeleteFileWithRetry(path);
}
File.Move(
this
._name, path);
}
this
.OnSaveEvent(ZipProgressEventType.Saving_BeforeRenameTempArchive);
File.Move((writeStream !=
null
) ? writeStream.CurrentTempName :
this
._temporaryFileName,
this
._name);
this
.OnSaveEvent(ZipProgressEventType.Saving_AfterRenameTempArchive);
if
(path !=
null
)
{
try
{
if
(File.Exists(path))
{
File.Delete(path);
}
}
catch
{
}
}
this
._fileAlreadyExists =
true
;
}
NotifyEntriesSaveComplete(entries);
this
.OnSaveCompleted();
this
._JustSaved =
true
;
}
}
}
finally
{
this
.CleanupAfterSaveOperation();
}
}
|
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
|
public
static
bool
IsZipFile(Stream stream,
bool
testExtract)
{
if
(stream ==
null
)
{
throw
new
ArgumentNullException(
"stream"
);
}
bool
flag =
false
;
try
{
if
(!stream.CanRead)
{
return
false
;
}
Stream @
null
= Stream.Null;
using
(ZipFile file = Read(stream,
null
,
null
,
null
))
{
if
(testExtract)
{
foreach
(ZipEntry entry
in
file)
{
if
(!entry.IsDirectory)
{
entry.Extract(@
null
);
}
}
}
}
flag =
true
;
}
catch
(IOException)
{
}
catch
(ZipException)
{
}
return
flag;
}
|
2.Read()读取数据流:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
private
static
ZipFile Read(Stream zipStream, TextWriter statusMessageWriter, Encoding encoding, EventHandler<ReadProgressEventArgs> readProgress)
{
if
(zipStream ==
null
)
{
throw
new
ArgumentNullException(
"zipStream"
);
}
ZipFile zf =
new
ZipFile {
_StatusMessageTextWriter = statusMessageWriter,
_alternateEncoding = encoding ?? DefaultEncoding,
_alternateEncodingUsage = ZipOption.Always
};
if
(readProgress !=
null
)
{
zf.ReadProgress += readProgress;
}
zf._readstream = (zipStream.Position == 0L) ? zipStream :
new
OffsetStream(zipStream);
zf._ReadStreamIsOurs =
false
;
if
(zf.Verbose)
{
zf._StatusMessageTextWriter.WriteLine(
"reading from stream..."
);
}
ReadIntoInstance(zf);
return
zf;
}
|
以上是对ZipFile类的一些方法的解析,提供了该组件的一些方法的源码,至于源码的解读上难度不是很大,至于该组件的API,可以在下载DLL文件后,可以直接查看相应的方法和属性,在这里就不做详细的介绍.
三.DotNetZip组件使用实例:
以上是对该组件的一些解析,接下来我们看看实例:
1.压缩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
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
|
/// <summary>
/// 压缩ZIP文件
/// 支持多文件和多目录,或是多文件和多目录一起压缩
/// </summary>
/// <param name="list">待压缩的文件或目录集合</param>
/// <param name="strZipName">压缩后的文件名</param>
/// <param name="isDirStruct">是否按目录结构压缩</param>
/// <returns>成功:true/失败:false</returns>
public
static
bool
CompressMulti(List<
string
> list,
string
strZipName,
bool
isDirStruct)
{
if
(list ==
null
)
{
throw
new
ArgumentNullException(
"list"
);
}
if
(
string
.IsNullOrEmpty(strZipName))
{
throw
new
ArgumentNullException(strZipName);
}
try
{
//设置编码,解决压缩文件时中文乱码
using
(var zip =
new
ZipFile(Encoding.Default))
{
foreach
(var path
in
list)
{
//取目录名称
var fileName = Path.GetFileName(path);
//如果是目录
if
(Directory.Exists(path))
{
//按目录结构压缩
if
(isDirStruct)
{
zip.AddDirectory(path, fileName);
}
else
{
//目录下的文件都压缩到Zip的根目录
zip.AddDirectory(path);
}
}
if
(File.Exists(path))
{
zip.AddFile(path);
}
}
//压缩
zip.Save(strZipName);
return
true
;
}
}
catch
(Exception ex)
{
throw
new
Exception(ex.Message);
}
}
|
2.解压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
37
38
39
40
41
42
43
44
|
/// <summary>
/// 解压ZIP文件
/// </summary>
/// <param name="strZipPath">待解压的ZIP文件</param>
/// <param name="strUnZipPath">解压的目录</param>
/// <param name="overWrite">是否覆盖</param>
/// <returns>成功:true/失败:false</returns>
public
static
bool
Decompression(
string
strZipPath,
string
strUnZipPath,
bool
overWrite)
{
if
(
string
.IsNullOrEmpty(strZipPath))
{
throw
new
ArgumentNullException(strZipPath);
}
if
(
string
.IsNullOrEmpty(strUnZipPath))
{
throw
new
ArgumentNullException(strUnZipPath);
}
try
{
var options =
new
ReadOptions
{
Encoding = Encoding.Default
};
//设置编码,解决解压文件时中文乱码
using
(var zip = ZipFile.Read(strZipPath, options))
{
foreach
(var entry
in
zip)
{
if
(
string
.IsNullOrEmpty(strUnZipPath))
{
strUnZipPath = strZipPath.Split(
'.'
).First();
}
entry.Extract(strUnZipPath,overWrite
? ExtractExistingFileAction.OverwriteSilently
: ExtractExistingFileAction.DoNotOverwrite);
}
return
true
;
}
}
catch
(Exception ex)
{
throw
new
Exception(ex.Message);
}
}
|
3.得到指定的输入流的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
37
38
39
40
41
42
|
/// <summary>
/// 得到指定的输入流的ZIP压缩流对象
/// </summary>
/// <param name="sourceStream">源数据流</param>
/// <param name="entryName">实体名称</param>
/// <returns></returns>
public
static
Stream ZipCompress(Stream sourceStream,
string
entryName =
"zip"
)
{
if
(sourceStream ==
null
)
{
throw
new
ArgumentNullException(
"sourceStream"
);
}
var compressedStream =
new
MemoryStream();
long
sourceOldPosition = 0;
try
{
sourceOldPosition = sourceStream.Position;
sourceStream.Position = 0;
using
(var zip =
new
ZipFile())
{
zip.AddEntry(entryName, sourceStream);
zip.Save(compressedStream);
compressedStream.Position = 0;
}
}
catch
(Exception ex)
{
throw
new
Exception(ex.Message);
}
finally
{
try
{
sourceStream.Position = sourceOldPosition;
}
catch
(Exception ex)
{
throw
new
Exception(ex.Message);
}
}
return
compressedStream;
}
|
4.得到指定的字节数组的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
|
/// <summary>
/// 得到指定的字节数组的ZIP解压流对象
/// 当前方法仅适用于只有一个压缩文件的压缩包,即方法内只取压缩包中的第一个压缩文件
/// </summary>
/// <param name="data"></param>
/// <returns></returns>
public
static
Stream ZipDecompress(
byte
[] data)
{
Stream decompressedStream =
new
MemoryStream();
if
(data ==
null
)
return
decompressedStream;
try
{
var dataStream =
new
MemoryStream(data);
using
(var zip = ZipFile.Read(dataStream))
{
if
(zip.Entries.Count > 0)
{
zip.Entries.First().Extract(decompressedStream);
// Extract方法中会操作ms,后续使用时必须先将Stream位置归零,否则会导致后续读取不到任何数据
// 返回该Stream对象之前进行一次位置归零动作
decompressedStream.Position = 0;
}
}
}
catch
(Exception ex)
{
throw
new
Exception(ex.Message);
}
return
decompressedStream;
}
|
四.总结:
以上是对DotNetZip组件的一些解析和方法实例,至于这款组件是不是最好的.NET压缩组件,这个就不做评价。个人在选择组件的时候,首先考虑的是开源,其次是免费,最后再考虑效率和实用性,毕竟在国内的一些情况是所有开发者都清楚的(不提国外是由于我不知道国外的情况)。客户需要降低成本,并且组件要可以进行定制。不过个人认为收费应该是一种趋势,毕竟所有的产品都是需要人员进行维护和开发。以上的博文中有不足之处,还望多多指正.
原文链接:http://www.cnblogs.com/pengze0902/p/6124659.html 。
最后此篇关于详解最好的.NET开源免费ZIP库DotNetZip(.NET组件介绍之三)的文章就讲到这里了,如果你想了解更多关于详解最好的.NET开源免费ZIP库DotNetZip(.NET组件介绍之三)的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
我有这个命令: 7z e -oD:\Data\ODS_Source\* D:\Data\DATA_DROP\Source.zip 这导致 D:\Data\ODS_Source\Source\. 我需要
我正在尝试让 Ionic zip 将 zip 文件内的文件夹提取到指定的根目录中。我的问题是里面的zip文件是“zipfile.zip\some_folder\”。我想将“some_folder”中的
我试图让 Ionic zip 将 zip 文件中的文件夹提取到指定的根目录中。我的问题是里面的 zip 文件是“zipfile.zip\some_folder\”。我想将“some_folder”中的
题目 监听服务器端口,得到题目如下: 源码解析 主函数 主函数中是题目界面的逻辑,对应于用户的选择做出相应的操作,其中需要注意的是选项2,解压操作需要获得root权
我有许多需要分发给用户的zip文件,其中约有130个。每个zip文件都包含许多相似的文本,html,xml和jpg文件。压缩文件总计146兆字节;解压缩后,其内容总计551mb。 我想将所有这些文件以
我正在使用 javascript zip.js图书馆。我到处搜索,但找不到将多个文件添加到 zip 的示例。 这是我的代码,但它生成了一个“损坏的”zip。 var len = results.row
在 C# 中,我使用的是 DotNetZip我有一个名为“innerZip.zip”的 zip,其中包含一些数据,和另一个名为“outerZip.zip”的 zip,其中包含 innerZip。我为什
当我使用 library(xlsx) 中的 write.xlsx 时,控制台中会出现以下内容: Note: zip::zip() is deprecated, please use zip::zipr
如果我因为问“非编程”问题而被拒绝,我不会太惊讶,但也许有人知道...... 我正在使用 WinXP 的内置“发送到压缩(zipped)文件夹”功能压缩我的 subversion 沙箱的内容,并惊讶地
我在 Elixir 中有一个二进制字符串,它由压缩字节组成,我想放气并从中提取“真实数据”: iex(93)> data > 我不确定如何解压缩这些数据。到目前为止,我已经: 浏览了 Official
有没有一种方法可以创建一个 zip 文件并强制它在命令行中包含数据描述符部分? 最佳答案 在 Github ( https://github.com/adamhathcock/sharpcompres
我已经有 PBDT.csj and RDK.csj使用此 ( https://www.blackberry.com/SignedKeys/codesigning.html ) 链接进行代码签名处理后的
我研究了几天,发现我们可以将一个包含一些内容的文件添加到 zip 文件中,然后再次压缩它。然后注释将被添加到 zip 文件中,但我不知道该文件到底是什么,所以任何人都知道向 zip(压缩)文件添加注释
我想知道如何找到 zip 文件的压缩级别。 7z 和 winzip 制作的 Zip 文件具有不同的级别评级,因此我想将其中的一些映射到其他工具中的相应级别。 store level 或 level 0
到目前为止,对于Zip文件的Mime类型,我已经看到: 应用程序/八位字节流 multipart / x-zip 应用程序/ zip 应用程序/ zip压缩的 应用程序/ x-zip压缩的 我想我的问
我已经在 google 上搜索、在 wiki 上搜索并阅读了 ZIP 的 RFC,但找不到有关 ZIP 中使用的确切算法的任何信息。 我找到了有关 ZIP == TAR + GZIP 的信息 但是,我
我有这些自解压 zip 文件,我正试图在 2008/7 机器上远程解压这些文件。但它们是以 .exe 的方式出现的,它需要用户双击并选择提取位置。 在 WinZip 支持网站上,他们说要使用/auto
这是我在这里的第一个问题,请耐心等待。 我的目标是在 C# 中创建一个基本的 .zip 存档。我已经尝试使用 .NET 的内置 GZipStream 类并设法实现了这一点,但是我遇到了一个问题,我无法
能否为压缩文件中的压缩文件创建 java.nio.file.FileSystem? 如果是这样,URI 是什么样的? 如果没有,我想我将不得不退回到使用 ZipInputStream。 我正在尝试递归
我想在 here 安装 scala我很关心下载哪一个:zip 还是 tgz。它们之间有什么区别,用例是什么? 最佳答案 它们是不同的archive formats .使用它们是因为它可以节省带宽并且因
我是一名优秀的程序员,十分优秀!