B4J Question Inconsistency in java.util.zip.ZipFile Code Snippet-Doesn't always return folders.

MrKim

Well-Known Member
Licensed User
Longtime User
Referring to THIS post I though how nice I can get and open zips without a lib BUT.
I modified ZipToMap and found it does not always return the Folders. Some zips it does, others it doesn't. Since the purpose of the code is to return file contents it is not an issue for ZipToMap but I was trying to build a tree. And the folders are sometimes missing. Specifically I saw the problem in this file: https://dl.google.com/android/repository/commandlinetools-win-9123335_latest.zip.

Has folders:
1768225865867.png

No Folders:
1768226019744.png

(Interestingly I even found on one zip with only two files and no subs it ADDED a root "/" entry. But perhaps that is because the two files were both themselves zip files.)
1768226174699.png

Here is the modified code I used:
B4X:
Private Sub ZipToMap (ZipPath As String, Fldr As String) As Map
'Private Sub ZipToMap (ZipPath As String) As Map
    Dim result As Map
    result.Initialize
    Dim ZipFile As JavaObject
    ZipFile.InitializeNewInstance("java.util.zip.ZipFile", Array(ZipPath))
    Dim enumeration As JavaObject = ZipFile.RunMethod("entries", Null)
    Do While enumeration.RunMethod("hasMoreElements", Null).As(Boolean)
        Dim ZipEntry As JavaObject = enumeration.RunMethod("nextElement", Null)
        Dim Name As String = ZipEntry.RunMethod("getName", Null)
        result.Put(Name, IIf(Name.EndsWith("/"), "Folder", "File"))
    Loop
    ZipFile.RunMethod("close", Null)
    Return result
End Sub
 

Erel

B4X founder
Staff member
Licensed User
Longtime User
The title is incorrect. The snippet works properly. It returns a map with the files.

You cannot assume that there are entries inside the zip for the folder themselves. This is not mandatory.
You should instead build the tree based on the files and if empty folders are important for you then also look for folder entries.

Example based on CLVTree: https://www.b4x.com/android/forum/threads/b4x-clvtree-tree-view.132472/#content

B4X:
Private Sub B4XPage_Created (Root1 As B4XView)
    Root = Root1
    Root.LoadLayout("MainPage")
    CustomListView1.DefaultTextBackgroundColor = xui.Color_White
    Tree.Initialize(CustomListView1)
    Dim files As Map = ZipToMap("C:\Users\H\Downloads\1.zip")
    For Each f As String In files.Keys
        Dim PathComponents() As String = Regex.Split("/", f)
        Dim FileName As String = PathComponents(PathComponents.Length - 1)
        Dim Folders As List = B4XCollections.CreateList(PathComponents)
        Folders.RemoveAt(Folders.Size - 1)
        Dim Parent As CLVTreeItem = Tree.Root
        For Each folder As String In Folders
            Dim child As CLVTreeItem = FindChildren(Parent, folder)
            If NotInitialized(child) Then
                child = Tree.AddItem(Parent, folder, Null, folder)
            End If
            Parent = child
        Next
        Tree.AddItem(Parent, FileName, Null, FileName)
    Next
End Sub

Private Sub FindChildren(Parent As CLVTreeItem, Value As String) As CLVTreeItem
    For Each c As CLVTreeItem In Parent.Children
        If c.Tag = Value Then Return c
    Next
    Return Null
End Sub

1768285500381.png
 
Upvote 0

MrKim

Well-Known Member
Licensed User
Longtime User
The title is incorrect. The snippet works properly. It returns a map with the files.


I did not mean to imply that the snippet was incorrect. I modified it. I did not know that the directory entries were separate but i figured it had something to do with the way the zips were created. I t never occurred to me that they would be a separate entry since they do not display as a separate entry. I am continuously astounded by the shear amount of information you retain.
 
Upvote 0
Top