Directory Scanning

I’ve been looking for a method of quickly scanning directories other than just using a shell command. I found this:

but can’t seem to get it to return anything. I’m running it on Win10, Xojo 2020 v2.1. Any help would be greatly appreciated.

that folderitem children method is to slow for you?

Unfortunately, yes. The implementation will be working with upwards of 10k files.

FileListMBS from the MBS plugins are faster than xojo. Maybe ask @Christian_Schmitz

Well, first it’s easy with FolderItem to iterate a folder inefficiently.
Like using iterator and looping from first to last is best.

Otherwise FileListMBS class may be available to scan folder. Key there is to use FileListMBS for folder, and then other FileListMBS for subfolders and not use intermediate FolderItem objects.

Change

Dim FindHandle As Integer = FindFirstFile("\\\\?\" + path + "*" + Chr(0), Result)

to

Dim FindHandle As Integer = FindFirstFile("\\?\" + path + "*" + Chr(0), Result)

and call it without escaping the \'s so:

Dim files() As String = GetFiles("C:\Path\To\Folder\")

Julian - That did the trick! I tried not escaping from each instance but somehow never removed both!

However, In large directories (10k files) it’s not picking up everything. Any thoughts?

Sorry for being an ill-mannered lout and forgetting to say…Thanks very much for the help, Julian!

No worries :smiley:

Hmm, looking over the code and the data structure there could be directories that have other flags set which wouldn’t be highlighted with a simple 16 check so you’d need to change:

If result.int32value(0) = 16 Then

to

If (result.int32value(0) And 16) = 16 Then

so it checks for the existence of the 16 flag (FILE_ATTRIBUTE_DIRECTORY) no matter what other flags are set.

Seems like I did the same correction last year Does anyone knows fastest way to search a filename in specific folder? :wink:

I hope this sorts it.

Again, a perfect fix! I can’t thank you enough!

Now I’ll get to work on trying to add a file mask and hopefully learn something in the process :slight_smile: :grinning:

1 Like

Simpler than I expected :grinning:

I added a parameter [Filemask()] to the function and then modified

for j as Int32 = 0 to d.Ubound
  Files.Append d(j)
next

To

for j as Int32 = 0 to d.Ubound
  For q as Integer=0 To FileMask.Ubound
    If d(j).Right(3)=FileMask(q) Then Files.Append d(j)
  next
next

The added parameter needs to be included in the call within the loop as well.

Overall, there’s an barely perceptible drop in execution speed which is absolutely tolerable. With 25k files it added less than .5 seconds.

Once again, many thanks Julian, I would have been struggling for days without your help! :+1:

You’re welcome, I’m glad you got it sorted :smiley:

  1. A small speed gain

Using d.Ubound in the loop will slowdown the whole process. Set that value into a variable and use the variable in the for line.

I would use something like:

Var j As Int32 // If this is faster than Integer
Var Cnt As Int32

Cnt = d.Ubound

For j = 0 To Cnt
  1. How slow ?
    How slow Windows 10 is when opening in the Explorer a Directory with >10K items can be ?
    (vs some items only)

Thanks for the suggestion Emile, I’ll incorporate it

1 Like