I don't know if this is already available, but I wrote these simple routines to manipulate ZIP files:
- ZIP_IsZIP(): check if specified file is a ZIP file
ZIP_FileCount(): count the number of files in ZIP file
ZIP_FileList(): get a list of filenames/sizes in ZIP file
ZIP_ExtractFiles(): extract files in ZIP file to folder
ZIP_ExtractFile(): extract specified file in ZIP to folder
Code: Select all
UseZipPacker()
#ZIP_USEPATHS = #True
#ZIP_ROOTONLY = #False
Structure _ZIPFile
Filename.S
Size.l
EndStructure
Prototype.l ZIP_Callback(Filename.S)
;- append trailing backslash to path (if needed)
Procedure.S TrailingBackslash(Path.S)
If Path
If Right(Path, 1) = "\"
ProcedureReturn Path
Else
ProcedureReturn Path + "\"
EndIf
EndIf
EndProcedure
;- check if specified file is ZIP
Procedure.l ZIP_IsZIP(ZIPFile.S)
hPack.l = OpenPack(#PB_Any, ZIPFile, #PB_PackerPlugin_Zip)
If hPack
IsZIP.l = #True
ClosePack(hPack)
EndIf
ProcedureReturn IsZIP
EndProcedure
;- get count of files in specified ZIP file
Procedure.l ZIP_FileCount(ZIPFile.S)
hPack.l = OpenPack(#PB_Any, ZIPFile, #PB_PackerPlugin_Zip)
If hPack
If ExaminePack(hPack)
While NextPackEntry(hPack)
If PackEntryType(hPack) = #PB_Packer_File
FileCount.l + 1
EndIf
Wend
EndIf
ClosePack(hPack)
ProcedureReturn FileCount
Else
; indicate open error
ProcedureReturn -1
EndIf
EndProcedure
;- get list of files/sizes in specified ZIP file
Procedure.l ZIP_FileList(ZIPFile.S, List ZIPFiles._ZIPFile())
ClearList(ZIPFiles())
hPack.l = OpenPack(#PB_Any, ZIPFile, #PB_PackerPlugin_Zip)
If hPack
If ExaminePack(hPack)
While NextPackEntry(hPack)
If PackEntryType(hPack) = #PB_Packer_File
AddElement(ZIPFiles())
With ZIPFiles()
\Filename = PackEntryName(hPack)
\Size = PackEntrySize(hPack)
EndWith
EndIf
Wend
EndIf
ClosePack(hPack)
ProcedureReturn ListSize(ZIPFiles())
Else
; indicate open error
ProcedureReturn -1
EndIf
EndProcedure
;- extract all files in specified ZIP file to specified folder
;- NB: can now specify 'use paths' or 'root only'
Procedure.l ZIP_ExtractFiles(ZIPFile.S, Folder.S, Paths.l = #ZIP_ROOTONLY, Callback.ZIP_Callback = 0)
hPack.l = OpenPack(#PB_Any, ZIPFile, #PB_PackerPlugin_Zip)
If hPack
FolderTB.S = TrailingBackslash(Folder)
If ExaminePack(hPack)
While NextPackEntry(hPack)
Select PackEntryType(hPack)
Case #PB_Packer_File
Filename.S = PackEntryName(hPack)
If Callback
Callback(Filename)
EndIf
If UncompressPackFile(hPack, FolderTB + Filename) >= 0
Count.l + 1
EndIf
Case #PB_Packer_Directory
If Paths = #ZIP_USEPATHS
; create subfolder
CreateDirectory(FolderTB + PackEntryName(hPack))
EndIf
EndSelect
Wend
EndIf
ClosePack(hPack)
ProcedureReturn Count
Else
; indicate open error
ProcedureReturn -1
EndIf
EndProcedure
;- extract specified file in specified ZIP file to specified folder
;- NB: this only works with files in the root folder of ZIP file
Procedure.l ZIP_ExtractFile(ZIPFile.S, Folder.S, FileInZIP.S)
hPack.l = OpenPack(#PB_Any, ZIPFile, #PB_PackerPlugin_Zip)
If hPack
FolderTB.S = TrailingBackslash(Folder)
FileSize.l = UncompressPackFile(hPack, FolderTB + FileInZIP, FileInZIP)
ClosePack(hPack)
; return uncompressed size of extracted file, -1 if error
ProcedureReturn FileSize
Else
; indicate open error
ProcedureReturn -1
EndIf
EndProcedure
;- example program
NewList FilesInZIP._ZIPFile()
; file extract callback
Procedure MyZIPCallback(Filename.S)
Debug Filename
EndProcedure
ZIPFile.S = OpenFileRequester("Select ZIP File", "C:\", "ZIP Files (*.zip)|*.zip|All Files (*.*)|*.*", 0)
If ZIPFile
; check if zip file
If ZIP_IsZIP(ZIPFile)
; count files in ZIP
MessageRequester("ZIP File: " + ZIPFile, Str(ZIP_FileCount(ZIPFile)) + " files")
; get list of filenames/sizes in ZIP
FileCount.l = ZIP_FileList(ZIPFile, FilesInZIP())
ForEach FilesInZIP()
With FilesInZIP()
message.S + \Filename + " " + Str(\Size) + #LF$
EndWith
Next
If MessageRequester("ZIP File: " + ZIPFile + " - Extract?", Str(FileCount) + " files" + #LF$ + #LF$ + message, #PB_MessageRequester_YesNo) = #PB_MessageRequester_Yes
; extract files to specified folder
Folder.S = PathRequester("Select Output Folder", "C:\")
If Folder
; extract one file
; extract files with/without callback
; NB: can now specify 'use paths' or 'root only'
FileCount.l = ZIP_ExtractFiles(ZIPFile, Folder, #ZIP_USEPATHS, @MyZIPCallback())
;FileCount.l = ZIP_ExtractFiles(ZIPFile, Folder)
MessageRequester("ZIP File: " + ZIPFile, Str(FileCount) + " files extracted")
EndIf
EndIf
Else
MessageRequester("ZIP File: " + ZIPFile, "File is not a ZIP file!", #MB_ICONERROR)
EndIf
EndIf