none
請問,用GZIP壓縮及解壓縮檔案的問題 RRS feed

  • 問題

  • 我在某論壇上有看到用 GZIP 壓縮 及 解壓縮 檔案,請問要怎麼才可以在壓縮檔案時,把原來的檔名(例:123.xls)

    寫入到壓縮檔裡呢?然後在解壓縮時就不用在自己輸入原來的檔名。

     

    ' 下面是壓縮檔案

    Public Sub CompressFile(ByVal sourceFile As String, ByVal destinationFile As String)

            If Not File.Exists(sourceFile) Then
                Throw New FileNotFoundException
            End If

            Dim sourceStream As FileStream = Nothing
            Dim destinationStream As FileStream = Nothing
            Dim compressedStream As GZipStream = Nothing
            Try

                ' 以下兩行是我用來把原本的檔名寫入到壓縮檔裡(不知道對不對)。

                Dim Str As String = "C:\Documents and Settings\Administrator\桌面\123.xls"
                My.Computer.FileSystem.WriteAllText(destinationFile, Str, True, System.Text.Encoding.Default)

                ' Read the bytes from the source file into a byte array
                sourceStream = New FileStream(sourceFile, FileMode.Open, FileAccess.Read, FileShare.Read)
                ' Read the source stream values into the buffer
                Dim buffer(sourceStream.Length - 1) As Byte
                Dim checkCounter As Integer = sourceStream.Read(buffer, 0, buffer.Length)

                If checkCounter <> buffer.Length Then
                    Throw New ApplicationException
                End If

                ' Open the FileStream to write to
                destinationStream = New FileStream(destinationFile, FileMode.Append, FileAccess.Write, FileShare.Write)

                ' Create a compression stream pointing to the destiantion stream
                compressedStream = New GZipStream(destinationStream, CompressionMode.Compress, False)

                ' Now write the compressed data to the destination file
                compressedStream.Write(buffer, 0, buffer.Length)

            Catch ex As ApplicationException
                MessageBox.Show(ex.Message)
            Finally
                ' Make sure we allways close all streams
                If sourceStream IsNot Nothing Then
                    sourceStream.Close()
                End If

                If compressedStream IsNot Nothing Then
                    compressedStream.Close()
                End If

                If destinationStream IsNot Nothing Then
                    destinationStream.Close()
                End If
            End Try
        End Sub

     

    ' 以下是解壓縮檔案(請問~要如何得到原本的檔名?)

    Public Sub DecompressFile(ByVal sourceFile As String, ByVal destinationFile As String)
            'make sure the source file is there
            If Not File.Exists(sourceFile) Then
                Throw New FileNotFoundException
            End If

            'Create the streams and byte arrays needed
            Dim sourceStream As FileStream = Nothing
            Dim destinationStream As FileStream = Nothing
            Dim decompressedStream As GZipStream = Nothing
            Dim quartetBuffer(4) As Byte

            Try
                'Read in the compressed source stream
                sourceStream = New FileStream(sourceFile, FileMode.Open)

                'Create a compression stream pointing to the destiantion stream
                decompressedStream = New GZipStream(sourceStream, CompressionMode.Decompress, True)

                'Read the footer to determine the length of the destiantion file
                Dim position As Integer = sourceStream.Length - 4
                sourceStream.Position = position
                sourceStream.Read(quartetBuffer, 0, 4)
                sourceStream.Position = 0
                Dim checkLength As Integer = BitConverter.ToInt32(quartetBuffer, 0)

                Dim buffer(checkLength + 100) As Byte
                Dim offset, total As Integer 'http://vsqa.net
                'Read the compressed data into the buffer
                While (True)
                    Dim bytesRead As Integer = decompressedStream.Read(buffer, offset, 100)

                    If bytesRead = 0 Then Exit While

                    offset += bytesRead
                    total += bytesRead
                End While

                'Now write everything to the destination file
                destinationStream = New FileStream(destinationFile, FileMode.Create)
                destinationStream.Write(buffer, 0, total)

                'and flush everyhting to clean out the buffer
                destinationStream.Flush()

            Catch ex As ApplicationException
                MessageBox.Show(ex.Message)
            Finally
                'Make sure we allways close all streams
                If sourceStream IsNot Nothing Then
                    sourceStream.Close()
                End If

                If decompressedStream IsNot Nothing Then
                    decompressedStream.Close()
                End If

                If destinationStream IsNot Nothing Then
                    destinationStream.Close()
                End If
            End Try

    2008年6月1日 上午 04:59

解答

  • GZip 不等於 Zip ,Zip 是 RFC1950 的規格,所以包含目錄的實作,GZip 是 RFC1952 的規格,僅有單一檔案的內容壓縮。

     

    GZip 在 Linux 上常與 tar 組合一起用,例如:package.tar.gz ,其中 tar 是不含壓縮的目錄、檔案封裝技術,再用 gz 針對已封裝的檔案壓縮。

     

    所以沒有檔名相關的設定,因為根本就沒有,習慣是在原始檔名後面加上副檔名 .gz 。

     

    線上手冊有個範例,包含檔案及目錄封裝:

    http://msdn2.microsoft.com/zh-tw/library/ywf6dxhx(VS.80).aspx

     

    其他問題可參考:

    GZipStream/DeflateStream 在壓縮二進位檔會造成檔案放大

    http://tlcheng.spaces.live.com/blog/cns!145419920BFD55A7!1886.entry

     

    在 .Net 3.0 起內見 Zip 壓縮,詳見 ZipPackage 類別說明。

     

     

     

    2008年6月1日 下午 12:22
    版主

所有回覆

  • GZip 不等於 Zip ,Zip 是 RFC1950 的規格,所以包含目錄的實作,GZip 是 RFC1952 的規格,僅有單一檔案的內容壓縮。

     

    GZip 在 Linux 上常與 tar 組合一起用,例如:package.tar.gz ,其中 tar 是不含壓縮的目錄、檔案封裝技術,再用 gz 針對已封裝的檔案壓縮。

     

    所以沒有檔名相關的設定,因為根本就沒有,習慣是在原始檔名後面加上副檔名 .gz 。

     

    線上手冊有個範例,包含檔案及目錄封裝:

    http://msdn2.microsoft.com/zh-tw/library/ywf6dxhx(VS.80).aspx

     

    其他問題可參考:

    GZipStream/DeflateStream 在壓縮二進位檔會造成檔案放大

    http://tlcheng.spaces.live.com/blog/cns!145419920BFD55A7!1886.entry

     

    在 .Net 3.0 起內見 Zip 壓縮,詳見 ZipPackage 類別說明。

     

     

     

    2008年6月1日 下午 12:22
    版主
  • HI,

     

    比較快的做法就是壓縮檔的檔名為檔名加上.gz當做副檔名, 解壓縮時將附加的.gz副檔名拿掉即可

     

    tihs

    2008年6月2日 上午 01:14