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

vb.net

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

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

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

Imports System.IO

Imports System.Text



Imports ICSharpCode

Imports ICSharpCode.SharpZipLib

Imports ICSharpCode.SharpZipLib.Zip

Imports ICSharpCode.SharpZipLib.Zip.Compression

Imports ICSharpCode.SharpZipLib.Core





Public Class ClsoZip



    '''<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 Sub



End Class

 

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

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

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

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

你可能感兴趣的:(VB.NET)