> Could someone advice me on how i could
> get the file names in a zip file.
You'll either need to use a third party .zip library, or parse the .zip
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
'***
Seek back 4 bytes and read in the entire structure in one shot, or read in
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
Private Function TestZip(ByRef inFile As String) As Long
Dim FileName As String
Dim ReadHead As typZipLocalFileHead
Dim FNum As Integer
Dim FileString As String
Dim SeekSize As Long
Const ZipLocalFileHeadSig As Long = &H4034B50
' Make sure file exists
If (Not FileExist(inFile)) Then Exit Function
' Get a free file handle and open the file
FNum = FreeFile()
Open inFile For Binary Access Read Lock Write As #FNum
Do ' Read a chunk signature
Get #FNum, , ReadHead.zlfhSignature
' Check for a local file header signatrue
If (ReadHead.zlfhSignature = ZipLocalFileHeadSig) Then
' Ok, read the full structure
Seek #FNum, Seek(FNum) - 4
Get #FNum, , ReadHead
With 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
' Print the compression percentage
Debug.Print " -- " & Format(1 - (.zlfhCompressedSize / _
.zlfhUncompressedSize), "0.0%")
' Work out how much extra data to skip over
SeekSize = .zlfhCompressedSize
If (.zlfhExtraFieldLength) Then _
SeekSize = SeekSize + .zlfhExtraFieldLength
If (.zlfhBitFlag And &H4) Then _
SeekSize = SeekSize + 12
' Seek to next record
Seek #FNum, Seek(FNum) + SeekSize
End With
' Increment file count
TestZip = TestZip + 1
Else
Exit Do
End If
Loop
Close #FNum
End Function
Private Function FileExist(ByVal inFile As String) As Boolean
On Error Resume Next
FileExist = FileLen(inFile) + 1
End Function
'***
Hope this helps,
Mike
- Microsoft Visual Basic MVP -
E-Mail: ED...@mvps.org
WWW: Http://www.mvps.org/EDais/