Thanks a lot, folks! I don't know where I got the idea from that there is an API for this on every platform, by now I believe that if there is a cached file count it is probably very filesystem-dependent and not easily accessible.
Here is what I'm using now (partly based on code by someone else, but I no longer know whom):
Code: Select all
DeclareModule FileHelpers
CompilerIf #PB_Compiler_OS = #PB_OS_Windows
#Path_Separator = "\"
CompilerElse
#Path_Separator = "/"
CompilerEndIf
Declare CountFiles(folder.s, pattern.s="*.*", recursive=#True, countOnlyVisible=#False)
Declare IsEmptyDirectory(folder.s)
EndDeclareModule
Module FileHelpers
Procedure CountFiles(folder.s, pattern.s="*.*", recursive=#True, countOnlyVisible=#False)
Protected count=0
Protected NewList ToDo.s(), hd
If Right(folder, 1) <> #Path_Separator : folder + #Path_Separator : EndIf
AddElement(ToDo())
ToDo() = folder
ResetList(ToDo())
While NextElement(ToDo())
folder = ToDo()
DeleteElement(ToDo())
hd = ExamineDirectory(#PB_Any, folder, pattern)
If hd
While NextDirectoryEntry(hd)
If DirectoryEntryType(hd) = #PB_DirectoryEntry_File
If countOnlyVisible
If GetFilePart(DirectoryEntryName(hd),#PB_FileSystem_NoExtension)<>""
count+1
EndIf
Else
count+1
EndIf
Else
If DirectoryEntryName(hd) <> "." And DirectoryEntryName(hd) <> ".." And recursive
AddElement(ToDo())
ToDo() = folder + DirectoryEntryName(hd) + #Path_Separator
EndIf
EndIf
Wend
FinishDirectory(hd)
EndIf
ResetList(ToDo())
Wend
ClearList(ToDo())
ProcedureReturn count
EndProcedure
Procedure IsEmptyDirectory(folder.s)
Protected result=#False
If CountFiles(folder)=0
result=#True
EndIf
ProcedureReturn result
EndProcedure
EndModule
It's reasonably fast, though I'm still looking for ways to get the count in constant time.
Edit: Corrected error with countOnlyVisible.