View Full Version : ZLIB_Extract-Bug when unpacking zips that contain folders
ReneMiner
21-02-2015, 16:16
It creates duplicates of the folders contained in a zip-file in app_scriptpath when unpacking not to app_scriptpath.
Creates empty folders + subfolders in app_scriptpath - as long as they contain data.
Empty folders- even if contained in the zip- won't get created at all - not at destination nor at app_scriptpath
I made some example and attached it- this is just the test-script, run it from the unpacked attachement which contains some example-source+destination-folder - it won't make a difference where they are located as long as destination is not app_scriptpath. Only in that case the misbehaviour of creating duplicate folders in app_scriptpath would not matter
Uses "Console", "ZLib"
String sZip_path = APP_ScriptPath & "some_subfolder\"
' some_subfolder means only NOT APP_SCRIPTPATH,
' can as well create some additional folder (as "c:\test\") where to unpack
ZLib_Extract(sZip_path & "some_zip_with_folders inside.zip", sZip_path)
' we dont unpack anything to App_Scriptpath here...
PrintL "check content of your current app_scriptpath now on disk: "
PrintL APP_ScriptPath
WaitKey
ReneMiner
22-02-2015, 09:55
ZLIB - if the above got fixed ... we need more of it.
We need functions that can retrieve single datafiles from within the zip without unpacking it, so we can use zip-folders as compressed archive by default
'maybe
String sData = ZLib_FileExtract( "myArchive.zip", "myData.dat" )
String sMore = ZLib_FileExtract( "myArchive.zip", "data\moreData.dat" )
' here "data\" means path inside the zip
If Len(sMore) = 0 Then
' obviously "data\moreData.dat" not available.
' should not throw Error but just return empty string, i.e. no data
Endif
ReneMiner
22-02-2015, 18:06
Back to the main-issue
Probably the reason for the misbehaviour is that it creates some temporary folders inside App_Scriptpath and Dir_Remove & win32-equivalent only will remove an empty directory.
This should help:
Uses "File"
Function DIR_Kill(ByVal sPath As String)
If RIGHT$(sPath, 1 ) <> "\" Then sPath &= "\"
Local sSubdir() As String
Local sFiles() As String
Local Index As Long
Local lDirs As Long = DIR_ListArray(sSubDir, sPath, "*", %FILE_SUBDIR)
Local lFiles As Long = DIR_ListArray(sFiles, sPath, "*", %FILE_NORMAL)
If lFiles Then
For Index = 1 To lFiles
FILE_Kill( sPath & sFiles(Index) )
Next
EndIf
If lDirs Then
For Index = 1 To lDirs
Dir_Kill(sPath & sSubdir(Index))
Next
EndIf
DIR_Remove(sPath)
End Function
something else i observed to FILE_Exist- it seems to return True for an existing PATH also,
but in this case...
Uses "console", "File"
String sFilename = "" ' <<< EMPTY STRING
If FILE_Exists(APP_ScriptPath & sFilename ) Then
PrintL "sFilename = " & $DQ & sFilename & $DQ & " seems to exist"
EndIf
WaitKey
it better should not
ReneMiner
24-02-2015, 15:51
Is it possible to tell ZLib to create a zip-file from a complete folder
- including all files and subfolders that are inside?
ReneMiner
25-02-2015, 16:47
yes it's possible!
This 2 small functions together will do it and create a zip of some folder including all its content in one go.
attachement below contains this script and some folder with data to test.
Uses "FILE", "ZLIB"
' ---------------------------------------------------------------------
Function ZLib_PackFolder(ByVal sFolder As String, _
Optional ByVal sZipfilename As String _
) As Boolean
' ---------------------------------------------------------------------
' this is the function to call for the user
' sFolder: full path to the folder to pack as zip
' sZipfilename: full path & filename
' if omitted the folders name
' will be taken and ".zip" gets appended
' it will pack a complete folder in one go
' -existing old zip-file will be deleted-
' this is NOT to ADD anything
If Not DIR_Exists(sFolder) Then Return FALSE
If Len(sZipFilename) = 0 Then
sZipFilename = Trim$(sFolder, "\") & ".zip"
EndIf
If RIGHT$(sFolder, 1) <> "\" Then
sFolder &= "\"
EndIf
If FILE_Exists(sZipFilename) Then
FILE_Kill(sZipfilename)
EndIf
' start with the initial directory:
ZLib_AddSubDir(sZipfilename, sFolder)
' close the zip finally
ZLib_AddEx(sZipfilename, "", %ZLIB_CLOSE)
' (ZLib_AddEx: helpfile is wrong here, it must be %ZLIB_, not %ZIP_)
' do we have data?
Function = (FILE_Size(sZipFilename) > 0)
End Function
' ---------------------------------------------------------------------
Function ZLib_AddSubDir(ByVal sZipfilename As String, _
ByVal sDir As String )
' ---------------------------------------------------------------------
' this function will add a subdir and all of its content
' (no hidden nor system-files) to a zipfile - it gets called
' from the function above if all is ok and then calls recursive
' itself until all data is added to the zip
' it will not copy empty directories into a zip !
Local sFile() As String
Local sPath() As String
Local nFiles As Long = DIR_ListArray(sFile, sDir, "*.*", %FILE_NORMAL)
Local nDirs As Long = DIR_ListArray(sPath, sDir, "*", %FILE_SUBDIR )
Local i As Long
If nFiles Then
For i = 1 To nFiles
ZLib_AddEx(sZIPFileName, sDir & sFile(i), %ZLIB_REL_PATH )
Next
EndIf
' calls itself:
If nDirs Then
For i = 1 To nDirs
ZLib_AddSubDir(sZipFilename, sDir & sPath(i) & "\" )
Next
EndIf
End Function
'-----------------------------------------------------------------
' functions-test
Uses "Console", "OS"
' there should be some testfolder here
' (download attachement below)
If ZLib_PackFolder(APP_ScriptPath & "testfolder") Then
PrintL "all packed"
' now should have a "testfolder.zip" in app_scriptpath
Else
PrintL "packing error"
EndIf
' let's check app_scriptpath:
OS_Shell("explorer.exe " & $DQ & APP_ScriptPath & $DQ)
PrintL
PrintL "all done, press any key to end"
WaitKey
ReneMiner
26-02-2015, 12:26
Improved the functions,
now it will accept an optional parameter to specify if hidden or system-files etc. shall be included to the package.
'just the new functions- no example... finally does the same as above.
Uses "FILE", "ZLIB"
' ---------------------------------------------------------------------
Function ZLib_PackFolder(ByVal sFolder As String, _
Optional ByVal sZipfilename As String, _
ByVal lFileTypes As Long = %FILE_NORMAL
) As Boolean
' ---------------------------------------------------------------------
' this is the function to call for the user
' sFolder: full path to the folder to pack as zip
' sZipfilename: full path & filename
' if omitted the folders name
' will be taken and ".zip" gets appended
' lFileTypes: combination of one or more FILE-module-equates
' only these are accepted/make sense:
' %FILE_NORMAL
' %FILE_READONLY
' %FILE_HIDDEN
' %FILE_SYSTEM
' %FILE_ARCHIVE
' it will pack a complete folder in one go
' -existing old zip-file will be deleted-
' this is NOT to ADD anything
Local lCheck As Long
If Not DIR_Exists(sFolder) Then Return FALSE
If Len(sZipFilename) = 0 Then
sZipFilename = Trim$(sFolder, "\") & ".zip"
EndIf
If RIGHT$(sFolder, 1) <> "\" Then
sFolder &= "\"
EndIf
If FILE_Exists(sZipFilename) Then
FILE_Kill(sZipfilename)
EndIf
' local check for valid flagged filetypes:
If (lFileTypes And %FILE_NORMAL) Then lCheck = %FILE_NORMAL
If (lFileTypes And %FILE_READONLY) Then lCheck = lCheck Or %FILE_READONLY
If (lFileTypes And %FILE_HIDDEN) Then lCheck = lCheck Or %FILE_HIDDEN
If (lFileTypes And %FILE_SYSTEM) Then lCheck = lCheck Or %FILE_SYSTEM
If (lFileTypes And %FILE_ARCHIVE) Then lCheck = lCheck Or %FILE_ARCHIVE
' start with the initial directory:
ZLib_AddSubDir(sZipfilename, sFolder, lCheck)
' close the zip finally
ZLib_AddEx(sZipfilename, "", %ZLIB_CLOSE)
' (ZLib_AddEx: helpfile is wrong here, it must be %ZLIB_, not %ZIP_)
' do we have data?
Function = (FILE_Size(sZipFilename) > 0)
End Function
' ---------------------------------------------------------------------
Function ZLib_AddSubDir(ByVal sZipfilename As String, _
ByVal sDir As String, _
ByVal lFileTypes As Long )
' ---------------------------------------------------------------------
' this function will add a subdir and all files inside that meet
' the specified type (usual %FILE_Normal) to a zipfile
' it gets called from the function above if all is ok and then calls
' itself until all data is added to the zip
' it will not copy empty directories into a zip !
Local sFile() As String
Local sPath() As String
Local nFiles As Long = DIR_ListArray(sFile, sDir, "*.*", lFileTypes )
Local nDirs As Long = DIR_ListArray(sPath, sDir, "*", %FILE_SUBDIR )
Local i As Long
If nFiles Then
For i = 1 To nFiles
ZLib_AddEx(sZIPFileName, sDir & sFile(i), %ZLIB_REL_PATH )
Next
EndIf
' calls itself:
If nDirs Then
For i = 1 To nDirs
ZLib_AddSubDir(sZipFilename, sDir & sPath(i) & "\", lFileTypes )
Next
EndIf
End Function