【.NET】利用SharpZipLib压缩与解压文件夹中的所有文件、内存中动态压缩解压数据、内存中压缩与解压文本

来源:互联网 发布:单相电动机绕组数据 编辑:程序博客网 时间:2024/06/10 04:36

SharpZipLib是一个非常优秀的.NET环境下的ZIP文档压缩与解压组件,免费且开源。

本篇文章介绍一下如何使用该组件压缩一个文件夹中的所有文件到ZIP文档、解压一个ZIP文档到文件夹,以及如何利用SharpZipLib在内存中动态的加解压数据。

下载最新版的SharpZipLib http://www.icsharpcode.net/OpenSource/SharpZipLib/Download.aspx

Imports System.IOImports System.TextImports ICSharpCodeImports ICSharpCode.SharpZipLibImports ICSharpCode.SharpZipLib.ZipImports ICSharpCode.SharpZipLib.Zip.CompressionImports ICSharpCode.SharpZipLib.CorePublic Class iZip ''' <summary>加压数据</summary> ''' <param name="data">数据</param> ''' <param name="offset">起始偏移</param> ''' <param name="length">长度</param> ''' <param name="level">压缩级别</param> Public Shared Function Compress(ByVal data As Byte(), Optional ByVal offset As Integer = 0, Optional ByVal length As Integer = -1, Optional ByVal level As Integer = 9) As Byte() If data Is Nothing OrElse data.Length = 0 Then Return Nothing If offset < 0 Then offset = 0 If length < 0 Then length = data.Length If level < 0 Then level = 1 If level > 9 Then level = 9 Dim ms As New MemoryStream Dim def As New Deflater def.SetLevel(level) def.SetInput(data, offset, length) Dim output(&H400 - 1) As Byte Do Until def.IsFinished Dim count As Integer = def.Deflate(output) ms.Write(output, 0, count) Loop Dim ret As Byte() = ms.ToArray ms.Close() Return ret End Function ''' <summary>加压字符</summary> ''' <param name="str">字符</param> ''' <param name="enc">编码</param> ''' <param name="level">压缩级别</param> Public Shared Function CompressString(ByVal str As String, Optional ByVal enc As Encoding = Nothing, Optional ByVal level As Integer = 9) As Byte() If enc Is Nothing Then enc = Encoding.Default Dim data As Byte() = enc.GetBytes(str) Return Compress(data, , , level) End Function ''' <summary>解压数据</summary> ''' <param name="data">数据</param> Public Shared Function Decompress(ByVal data As Byte()) As Byte() If data Is Nothing OrElse data.Length < 1 Then Return Nothing Dim ms As New MemoryStream Dim inf As New Inflater inf.SetInput(data) Dim buffer(&H400 - 1) As Byte Do Until inf.IsFinished Dim count As Integer = inf.Inflate(buffer) ms.Write(buffer, 0, count) Loop Dim ret As Byte() = ms.ToArray ms.Close() Return ret End Function ''' <summary>解压字符</summary> ''' <param name="data">数据</param> ''' <param name="enc">编码</param> Public Shared Function DecompressString(ByVal data As Byte(), Optional ByVal enc As Encoding = Nothing) As String If enc Is Nothing Then enc = Encoding.Default Dim bs As Byte() = Decompress(data) Return enc.GetString(bs) End Function ''' <summary>快速加压</summary> Public Shared Sub FastCreateZip(ByVal zipPath As String, ByVal folderPath As String, Optional ByVal fileFilter As String = "", Optional ByVal password As String = Nothing) Dim fz As New FastZip If password <> Nothing Then fz.Password = password fz.CreateZip(zipPath, folderPath, True, fileFilter) End Sub ''' <summary>快速解压</summary> Public Shared Sub FastExtractZip(ByVal zipPath As String, ByVal folderPath As String, Optional ByVal fileFilter As String = "", Optional ByVal password As String = Nothing) Dim fz As New FastZip If password <> Nothing Then fz.Password = password fz.ExtractZip(zipPath, folderPath, fileFilter) End Sub ''' <summary>解压ZIP文件到目录</summary> ''' <param name="zipPath">ZIP文件路径</param> ''' <param name="folderPath">目标文件夹</param> ''' <param name="password">密码</param> ''' <param name="overwrite">是否覆盖文件</param> Public Shared Sub DecompressZip(ByVal zipPath As String, ByVal folderPath As String, Optional ByVal password As String = Nothing, Optional ByVal overwrite As Boolean = True) ' 初始化文档、密码、目标文件夹路径 Dim z As New ZipInputStream(File.OpenRead(zipPath)) If password <> Nothing Then z.Password = password If folderPath = Nothing Then 'folderPath = HttpContext.Current.Server.MapPath("~/") folderPath = Application.StartupPath End If If Not folderPath.EndsWith("\") Then folderPath &= "\" If Not Directory.Exists(folderPath) Then Directory.CreateDirectory(folderPath) Dim t As ZipEntry Dim fp As String ' 开始循环解压 Do t = z.GetNextEntry If t Is Nothing Then Exit Do fp = folderPath & t.Name ' 如果是文件夹则创建文件夹 If t.IsDirectory AndAlso Not Directory.Exists(fp) Then Directory.CreateDirectory(fp) ElseIf t.IsFile Then ' 如果是文件则解压文件 If (Not File.Exists(fp)) OrElse (File.Exists(fp) And overwrite) Then Dim sw As FileStream = File.Create(fp) Dim size As Integer Dim data(2048) As Byte Do '循环读取数据 size = z.Read(data, 0, data.Length) If size = 0 Then Exit Do sw.Write(data, 0, size) Loop sw.Close() File.SetLastWriteTime(fp, t.DateTime) '更新创建日期 End If End If Loop z.Close() End Sub ''' <summary>压缩某个目录内全部文档到ZIP</summary> ''' <param name="zipPath">ZIP路径</param> ''' <param name="folderPath">目标目录</param> ''' <param name="level">压缩级别</param> ''' <param name="password">密码</param> Public Shared Sub CompressFile(ByVal zipPath As String, ByVal folderPath As String, Optional ByVal level As Integer = 9, Optional ByVal password As String = Nothing) If Not Directory.Exists(folderPath) Then Return If folderPath.EndsWith("\") Then folderPath &= "\" Dim z As New ZipOutputStream(File.Create(zipPath)) z.SetLevel(level) If password <> Nothing Then z.Password = password Dim fn As String, buffer(4096) As Byte Dim di As Integer = folderPath.Length + 1 ' 先将主目录下所有文件加入文档 For Each f As String In Directory.GetFiles(folderPath, "*", SearchOption.TopDirectoryOnly) fn = f.Remove(0, di) z.PutNextEntry(New ZipEntry(fn)) ' 将文件数据写入ZIP Using fs As FileStream = File.OpenRead(f) StreamUtils.Copy(fs, z, buffer) End Using Next ' 枚举所有文件夹 For Each d As String In Directory.GetDirectories(folderPath, "*", SearchOption.AllDirectories) fn = d.Remove(0, di) & "\" z.PutNextEntry(New ZipEntry(fn)) ' 枚举所有文件 For Each f As String In Directory.GetFiles(d, "*", SearchOption.TopDirectoryOnly) fn = f.Remove(0, di) z.PutNextEntry(New ZipEntry(fn)) Using fs As FileStream = File.OpenRead(f) StreamUtils.Copy(fs, z, buffer) End Using Next Next z.Close() End SubEnd Class


其中数据动态加解压的代码分析来自Lucene.NET,其他的是参考网络上部分文章(来源不可考)。

我稍微封装了一下SharpZipLib的方法,可以更实用更方便一些。

实际上SharpZipLib有一个FastZip类,也很方便,但效率就稍微比自己写的方法低了一点。

代码未严格测试,有BUG或建议请指正。


原创粉丝点击