PDA

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