B4J Code Snippet Folder size

Author: Erel

Note that it ignores subfolders.

B4X:
Sub SizeOfFilesInFolder(f As String) As Long
   Dim total As Long
   For Each filename As String In File.ListFiles(f)
     If File.IsDirectory(f, filename) = False Then
       total = total + File.Size(f, filename)
     End If
   Next
   Return total
End Sub
 

Magma

Expert
Licensed User
Longtime User
...Well old days created this...

- With this you can read also subfolders... actually using some recursive technique...
- Also you can add other folders to list, or files... like select them for "some" use..

B4X:
private Sub generatelistfolder(genlist As List, ffolder As String) As ResumableSub
 
 
    Dim alist As List
    alist.Initialize
    alist.Clear
 
    Try
        alist=File.ListFiles(ffolder)
    Catch
        Log("Not a Folder, may be a file... will try to add at list if exists...")
    End Try
 
    If alist.Size>0 Then
 

    For k=0 To alist.Size-1
        Dim isfolder As Boolean=File.IsDirectory(ffolder,alist.Get(k))
        
        If isfolder=True Then
            genlist.Add(Array As String(ffolder,alist.Get(k),isfolder))
            If ffolder.EndsWith("\")=True Then
                ffolder=ffolder.SubString2(0,ffolder.Length-1)
            End If
            generatelistfolder(genlist, ffolder & "\" & alist.Get(k))
        Else
            genlist.Add(Array As String(ffolder,alist.Get(k),isfolder))
        End If
    Next
 
    Else
    
        If File.Exists(File.GetFileParent(ffolder),File.GetName(ffolder)) Then
            genlist.add(Array As String(File.GetFileParent(ffolder),File.GetName(ffolder),False))
            Else
            Log ("Not Existing File...")
        End If
    
    End If

Return True

End Sub


You can use it like here:

B4X:
Dim mylist As List  'Here will save the names of Folders, Files and it is folder or file...
Dim totsize As Long=0
mylist.Initialize
mylist.clear

wait for(generatelistfolder(mylist,"D:\tesssst")) complete (s As Boolean) 'add one folder with subfolders
wait for(generatelistfolder(mylist,"c:\ccc")) complete (s As Boolean) 'add a second one... "
wait for(generatelistfolder(mylist,"d:\tameiakh.txt")) complete (s As Boolean) 'add a file at list... "

'Show the Folder | FileName | Is it Folder?
'--------------------------------------------
For k=0 To mylist.Size-1
    Dim FileOrFolderInfo() As String = mylist.Get(k)
    Log(FileOrFolderInfo(0) & " | " & FileOrFolderInfo(1) & " | " & FileOrFolderInfo(2))
    If FileOrFolderInfo(2)=False Then
        totsize=totsize+File.Size( FileOrFolderInfo(0), FileOrFolderInfo(1))
    End If
Next
Log("Total Size in bytes: " & totsize)
Log("Files & Folders Listed: " & mylist.Size)
 

LucaMs

Expert
Licensed User
Longtime User
The reason why I was looking for how to get the size of a folder (I was hoping to find a "direct" command, Java, but I found this, which was enough, I "transcribed" here it and if you think about it for a moment it is also multiplatform. Now, though, I'm about to start looking for a direct command.)

Windows 7 Explorer. When I hover the mouse cursor over a folder, sometimes a popup appears giving me the size of it but not always . So I'm afraid I'll have to develop a little (B4J) tool that lists the folder names and their size.
 

LucaMs

Expert
Licensed User
Longtime User
I'm about to start looking for a direct command.
ChatGPT "says" that the following Java function should work:

B4X:
    public static long getSizeOfFolder(String folderPath) throws IOException {
        Path path = Paths.get(folderPath);
        if (!Files.isDirectory(path)) {
            throw new IllegalArgumentException("La directory specificata non esiste o non è una cartella.");
        }

        FileStore fileStore = Files.getFileStore(path);
        return fileStore.getTotalSpace() - fileStore.getUnallocatedSpace();
    }
 

Daestrum

Expert
Licensed User
Longtime User
Your ChatGPT version just returns the used space of my disk irrespective of which folder I choose.

try this
B4X:
import java.io.*;
import java.nio.file.*;
public static long folderSize(String pth) throws IOException {
    Path folder = Paths.get(pth);
    long size = Files.walk(folder)
      .filter(p -> p.toFile().isFile())
      .mapToLong(p -> p.toFile().length())
      .sum();
    return size / 1_048_576;  // (MiB)
}
 
Last edited:

LucaMs

Expert
Licensed User
Longtime User
With the help of ChatGPT (to whom I had to teach many things about B4J , who knows if it will remember them) I obtained this function (still to be thoroughly tested):
B4X:
Sub GetSizeOfFolder(FolderPath As String) As Long
    Try
        Dim objFiles As JavaObject
        objFiles.InitializeStatic("java.nio.file.Files")
       
        Dim FolderFile As JavaObject
        FolderFile.InitializeNewInstance("java.io.File", Array As Object(FolderPath))
        Dim Path As JavaObject
        Path = FolderFile.RunMethod("toPath", Null)
     
        If Not(File.IsDirectory(FolderPath, "")) Then
            Log("The specified directory does not exist or is not a folder.")
            Return -1
        End If
       
        Dim FileStore As JavaObject
        FileStore = objFiles.RunMethod("getFileStore", Array As Object(Path))
        Dim TotalSpace As Long
        TotalSpace = FileStore.RunMethod("getTotalSpace", Null)
        Dim UnallocatedSpace As Long
        UnallocatedSpace = FileStore.RunMethod("getUnallocatedSpace", Null)
       
        Return TotalSpace - UnallocatedSpace
    Catch
        Log(LastException)
        Return -1
    End Try
End Sub

And after all this effort, maybe this function is slower than the one written by Erel.
 

LucaMs

Expert
Licensed User
Longtime User
Thanks @Daestrum, but... I can not
I don't know whether to use JavaObject (as I asked ChatGPT to do, see my previous post), Reflection or Inline Java.
 

Daestrum

Expert
Licensed User
Longtime User
Looking at the api, it appears filestore is drive/volume based.
Storage for files. A FileStore represents a storage pool, device, partition, volume, concrete file system or other implementation specific means of file storage. The FileStore for where a file is stored is obtained by invoking the getFileStore method
 

stevel05

Expert
Licensed User
Longtime User
I vaguely remember looking for something similar a while ago. I think my conclusion was that the information is not stored by the OS and is calculated as needed. Probably by iterating the files in the directory. Needless to say I didn't find a better solution, that's not to say there isn't one.
 

Magma

Expert
Licensed User
Longtime User
(general talking)

Correct me if I am wrong.... the filesystem would have to pay the cost of maintaining these counts every time a new file was created or deleted, instead of right now, where the filesystem doesn't have to...

1. So this will be a cost of Indexing... and keep size info too ---> less free space
2. Slower access
3. ...

Even at ubuntu... need to count every time the folders and the files... to give me the size when right click / properties...
 

Magma

Expert
Licensed User
Longtime User
* also, I remember... when searching too about faster proccessing those... was using MFT - but this will need i think some special jar library may be targetting .Net

* also at powershell terminal seems that searching folders is much faster... than IDE... Get-ChildItem -Recurse | Measure-Object).Count
 

LucaMs

Expert
Licensed User
Longtime User
Yes, I think I need to use a B4J recursive Sub, which I assume is the same thing the following Java command does:
Files.walk(folder)


[Also, I was wrong to write this stuff here; I was in too much of a hurry when I created this thread and I didn't look carefully at either the code or the name of the function created by Erel, which is useful but not what I need]
 

Magma

Expert
Licensed User
Longtime User
Don't worry... this is a productive thread for all... I think will help others and ourselves to find better and faster solutions...

* It is nice to sharing
 

Daestrum

Expert
Licensed User
Longtime User
That code I posted is the fastest I've found, as it uses nio.
I get times of around 35ms to execute on a 350MB folder.

Odlly enough (I know not to do with this thread ) but if I run B4J as administrator (for access permissions etc) it takes longer.
 

LucaMs

Expert
Licensed User
Longtime User
That code I posted is the fastest I've found, as it uses nio.
I get times of around 35ms to execute on a 350MB folder.

Odlly enough (I know not to do with this thread ) but if I run B4J as administrator (for access permissions etc) it takes longer.
Ok, but you know how to use that Java code, I don't ("Java object"? Recflection? "Inline Java"? I absolutely need to spend some time studying how to pass and receive parameters to Inline Java code! Damn laziness )
 
Cookies are required to use this site. You must accept them to continue using the site. Learn more…