1. 程式人生 > 其它 >解壓zip_VBA解壓縮ZIP檔案03——解壓準備工作

解壓zip_VBA解壓縮ZIP檔案03——解壓準備工作

技術標籤:解壓zip

f8a90ccfefc3bba3d1b8868d1c61bc16.png

要解壓縮ZIP檔案,所以肯定需要讀寫檔案的功能,為了方便,把VBA中對檔案的讀寫功能進行一個簡單的封裝,方便使用。

ZIP檔案壓縮後,儲存資料使用的最小單位是bit,注意不是Byte,計算機的1Byte=8bit,正常在VBA中操作的最小單位是Byte,為了方便讀取bit位的資料,寫幾個簡單的函式。

01 CFile檔案讀寫

主要是使用類模組對檔案操作Open、Put、Get等關鍵字的簡單封裝,這樣使用起來就更加的方便。

Public Enum OpenAccess    O_RDONLY    O_WRONLY    O_RDWREnd EnumPublic Enum SeekPos    OriginF    CurrentF    EndFEnd Enum'注意大檔案long型別會溢位Private lFileLen As LongPrivate num_file As Integer'寫入檔案Function WriteFile(b() As Byte) As Long    Put #num_file, , bEnd Function'讀取len(b)個byteFunction Read(b() As Byte) As Long    Dim ilen As Long    ilen = UBound(b) - LBound(b) + 1    Dim iseek As Long    iseek = VBA.Seek(num_file)    If iseek + ilen > lFileLen Then        ilen = lFileLen - iseek + 1    End If    Get #num_file, , b    Read = ilenEnd Function'讀取一個2Byte的整數Function ReadInteger() As Integer    Dim i As Integer    Get #num_file, , i    ReadInteger = iEnd Function'讀取1個4Byte的整數Function ReadLong() As Long    Dim i As Long    Get #num_file, , i    ReadLong = iEnd Function'在offset處開始讀取Function ReadAt(b() As Byte, offset As Long) As Long    SeekFile offset, 0    ReadAt = Read(b)End Function'設定讀取的位置Function SeekFile(offset As Long, whence As SeekPos) As Long    Dim iseek As Long    iseek = VBA.Seek(num_file)    'vba Seek是下標1開始    If whence = SeekPos.OriginF Then        iseek = 1 + offset    ElseIf whence = SeekPos.CurrentF Then        iseek = iseek + offset    Else        iseek = 1 + lFileLen - offset    End If    Seek #num_file, iseek    SeekFile = iseekEnd Function'以位元組方式讀取文字Function OpenFile(Filename As String, Optional m As OpenAccess = OpenAccess.O_RDWR) As Long    '避免多次呼叫OpenFile的時候,前面的檔案未關閉    If num_file Then Close #num_file    num_file = VBA.FreeFile    Select Case m        Case OpenAccess.O_RDONLY        Open Filename For Binary Access Read As #num_file        Case OpenAccess.O_WRONLY        Open Filename For Binary Access Write As #num_file        Case OpenAccess.O_RDWR        Open Filename For Binary Access Read Write As #num_file        Case Else    End Select    lFileLen = VBA.FileLen(Filename)End FunctionFunction CloseFile()    Close #num_fileEnd FunctionPrivate Sub Class_Terminate()    CloseFileEndSub
02 bit位操作

計算機中1Byte=8bit,bit的排列順序和數學中的個位、十位、百位……是一樣的:

06da13d7f6d211c0f514885c9ee895dc.png

解壓ZIP的過程中,需要不停的從壓縮資料的Byte陣列中讀取需要的bit,實現幾個簡單的函式:

'取某一位的BitFunction GetBitFromByte(b As Byte, ZeroBaseIndex As Long) As Long    GetBitFromByte = VBA.CLng(b) And (2 ^ ZeroBaseIndex)    If GetBitFromByte > 0 Then        GetBitFromByte = 1    Else        GetBitFromByte = 0    End IfEnd Function
'從Byte陣列中取某一位的BitFunction GetBit(b() As Byte, ZeroBaseIndex As Long) As Long    '陣列b中,開始的下標    Dim bindex As Long    bindex = ZeroBaseIndex \ 8    GetBit = VBA.CLng(b(bindex)) And (2 ^ (ZeroBaseIndex Mod 8))    If GetBit > 0 Then        GetBit = 1    Else        GetBit = 0    End IfEnd Function
'從Byte陣列中取多位bit' 0000 0000     0000 0000' 7654 3210     fedc ba98Function GetBits(b() As Byte, IndexFromZeroBase As Long, iBits As Long) As Long    Dim i As Long    Dim tmp As Long    For i = 0 To iBits - 1        tmp = GetBit(b, IndexFromZeroBase + i)        tmp = BitMoveLeft(tmp, i)        GetBits = GetBits Or tmp    NextEnd Function'左移Function BitMoveLeft(ByRef l As Long, num As Long) As Long    Dim i As Long    For i = 1 To num        '會溢位 0x7FFF FFFF        '判斷第31位是否=1        '不管等不等於1都把第31為置換為0,負數待處理        l = l And &H3FFFFFFF        l = l * 2    Next    BitMoveLeft = lEnd Function'右移Function BitMoveRight(ByRef l As Long, num As Long) As Long    Dim i As Long    For i = 1 To num        l = l \ 2    Next    BitMoveRight = lEnd Function
'從Byte陣列中取多位bit'取出後的bit儲存順序倒置Function GetBitsRev(b() As Byte, IndexFromZeroBase As Long, iBits As Long) As Long    Dim i As Long    Dim tmp As Long    For i = 0 To iBits - 1        tmp = GetBit(b, IndexFromZeroBase + i)        tmp = BitMoveLeft(tmp, iBits - i - 1)        GetBitsRev = GetBitsRev Or tmp    NextEnd Function
d26341089981faa4c771196d8d2754c8.gif
  • 00ZIP是什麼

  • 01實現的功能

  • 02 壓縮過程

8336e3ce350abf8664159d7d86b9fdbb.png