What is the fastest method to get the number of files in a folder?

What is the fastest method to get the number of files in a folder?
Xojo method:

Var folder As FolderItem = SpecialFolder.Desktop.Child("FolderName")
If folder <> Nil And folder.Exists And folder.IsFolder Then
    Var count As Integer = 0
    Var item As FolderItem
    Var iterator As FolderItemIterator = folder.Children
    While iterator.HasNextItem
        item = iterator.NextItem
        If item <> Nil Then
            count = count + 1
        End If
    Wend
    MessageBox("Number of files : " + count.ToString)
End If

Shell method:

Var sh As New Shell
sh.Execute("find '/chemin/vers/dossier' -type f | wc -l")
Var result As String = sh.Result.Trim
MessageBox("Number of files : " + result)

MBS method:

Var folder As New FolderItemMBS(SpecialFolder.Desktop.Child("NomDossier"))
If folder <> Nil And folder.Exists And folder.Directory Then
    Var files() As FolderItemMBS = folder.Children
    MessageBox("Number of files : " + files.Count.ToString)
End If

Thanks

Well, what is your result when comparing the methods? I prefer to use the MBS method which is way faster. As far as I remember the conversion to folderitems takes a long time. I need a list of folderitems for potentially large folders.

What about FolderItem.Count?

7 Likes

There is also FileListMBS that you could try.

This class is made to get a list of files in a folder faster than by using a folderitem.

https://www.monkeybreadsoftware.net/class-filelistmbs.shtml

For Windows:

Public Function GetFilesCount(Path As String) As integer
  #pragma DisableBackgroundTasks  
  
  var fileCount As Integer = 0
  
  
  If path.Right(1) <> "\" Then path = path + "\"
  
  Declare Function FindFirstFile Lib "Kernel32" Alias "FindFirstFileW" (FileName As WString, FindData As Ptr) As Integer
  Declare Function FindNextFile Lib "Kernel32" Alias "FindNextFileW" (FindHandle As Integer, FindData As Ptr) As Boolean
  Declare Function FindClose Lib "Kernel32" (FindHandle As Integer) As Boolean
  
  
  var findData As New MemoryBlock(592)  
  var findHandle As Integer = FindFirstFile("\\?\" + path + "*" + Chr(0), findData)
  
  
  If findHandle > 0 Then
    Do
      ' PrĂĽfen: keine Verzeichnisse
      
      If (findData.Int32Value(0) And &h10) = 0 Then
        fileCount = fileCount + 1
      End If
    Loop Until Not FindNextFile(findHandle, findData)
    Call FindClose(findHandle)
  End If
  
  #pragma enableBackgroundTasks  
  Return fileCount
End Function

La commande “count” est la commande la plus indiquée.
Vous pouvez aussi utiliser la boucle ci apres pour une analyse plus fine

The “count” command is the most indicated command.
You can also use the loop below for a more detailed analysis

Var nb As Integer = folder.Count

Var nb_F As Integer 
Var nb_D As Integer 
Var nb_V As Integer 
 Var nb_I As Integer 

For Each item As FolderItem In folder.Children
  If item.IsFolder Then
    nb_F = nb_F + 1
  Else
    nb_D = nb_D + 1
  End If
  If item.Visible Then
    nb_V = nb_V + 1
  Else
    nb_I = nb_I + 1
  End If
Next

you could memory the datetime before and after the task is done and compare the time.
be aware that the use of shell commands, plug-ins, libraries are os specific.

Some time ago I worked on some C++ code for fun to do that (listing also the folders contents recursively). Maybe I can wrap it into an OpenSource plugin if I can find some spare time.

Some metrics: Retrieving the full paths for 5107 files → 93 milliseconds

1 Like

@Javier_Menendez - pretty cool. :sunglasses:

Maybe there’s an additional opportunity here to show best practices on putting together a simple plugin with latest Xojo builds? Just thinking out loud here.

2 Likes