| |
microsoft.public.vb.general.discussion |
'*** Seek back 4 bytes and read in the entire structure in one shot, or read in '*** Private Function TestZip(ByRef inFile As String) As Long Const ZipLocalFileHeadSig As Long = &H4034B50 ' Make sure file exists ' Get a free file handle and open the file ' Check for a local file header signatrue With ReadHead ' Print the compression percentage ' Work out how much extra data to skip over ' Seek to next record ' Increment file count Private Function FileExist(ByVal inFile As String) As Boolean Hope this helps, Mike - Microsoft Visual Basic MVP -
> get the file names in a zip file.
central directory structure. The format isn't _too_ tricky to parse,
(Assuming you're not dealing with multiple spanned volumes, but even so,
they're not really that much worse) since even when the file is encrypted,
the file header (Including file names) data is stored unencrypted.
A real rough overview of how to read a .ZIP file would be, enter a Do loop
and read 4 bytes from the file, these 4 byte should be a zip signature but
you're only interested in one type which comes at the start of the file, so
check for 0x4034B50. If the signature matches then you're looking at a
local file header structure which is declared as:
Private Type typZipLocalFileHead ' 30 bytes
zlfhSignature As Long ' 0x04034B50
zlfhVersion As Integer
zlfhBitFlag As Integer
zlfhCompression As Integer
zlfhModFileTime As Integer
zlfhModFileData As Integer
zlfhCRC As Long
zlfhCompressedSize As Long
zlfhUncompressedSize As Long
zlfhFileNameLength As Integer
zlfhExtraFieldLength As Integer
End Type
'***
the rest of the structure's fields individually. Now check the
zlfhFileNameLength field for a positive integer, if so then create a string
of that length and read it in from the file - That's the first filename.
You can also get compression ratio and other information about the file from
the structure depending on what you want to do with it.
Check the zlfhExtraFieldLength field for a positive integer, and if found
skip over that data
Finally, check the 3'rd bit of the zlfhBitFlag member (zlfhBitFlag And &H4)
and if present skip the next 12 bytes (Just a CRC and file sizes again.)
Keep going until you hit a different zip chunk signature and you should have
all your files, here's a quick example of the finished routine:
Private Sub Form_Load()
SET THE ZIP PATH HERE THEN KILL THIS LINE
Const FileName As String = "X:\Path\File.zip"
Debug.Print "Found " & TestZip(FileName) & " files in zip"
End Sub
Dim FileName As String
Dim ReadHead As typZipLocalFileHead
Dim FNum As Integer
Dim FileString As String
Dim SeekSize As Long
If (Not FileExist(inFile)) Then Exit Function
FNum = FreeFile()
Open inFile For Binary Access Read Lock Write As #FNum
Do ' Read a chunk signature
Get #FNum, , ReadHead.zlfhSignature
If (ReadHead.zlfhSignature = ZipLocalFileHeadSig) Then
' Ok, read the full structure
Seek #FNum, Seek(FNum) - 4
Get #FNum, , ReadHead
' Get the file name
If (.zlfhFileNameLength) Then
FileString = Space(.zlfhFileNameLength)
Get #FNum, , FileString
Debug.Print "Got file: """ & FileString & """";
Else ' No filename?
Debug.Print "Got file: [No name]";
End If
Debug.Print " -- " & Format(1 - (.zlfhCompressedSize / _
.zlfhUncompressedSize), "0.0%")
SeekSize = .zlfhCompressedSize
If (.zlfhExtraFieldLength) Then _
SeekSize = SeekSize + .zlfhExtraFieldLength
If (.zlfhBitFlag And &H4) Then _
SeekSize = SeekSize + 12
Seek #FNum, Seek(FNum) + SeekSize
End With
TestZip = TestZip + 1
Else
Exit Do
End If
Loop
Close #FNum
End Function
On Error Resume Next
FileExist = FileLen(inFile) + 1
End Function
'***
E-Mail: ED...@mvps.org
WWW: Http://www.mvps.org/EDais/