File Search speed

from somewhere-I-dont-remember of this forum…

[code]

Function ItemNames(extends f as folderItem, ReturnFileNames as boolean = true, ReturnFolderNames as boolean = true) As String()
// Returns an array containing the names of child items
// within the given folder item. Returns files and/or
// folders, as directed by the input booleans.
//
// Returns an empty array if f doesn’t exist, or if f
// isn’t a directory, or if both input booleans are false.
//
// The iteration is not recursive. On Windows, the special
// directories “.” and “…” are ignored.

dim result() as string

if f.Directory then

#if TargetWin32
  
  // On Windows, RB's f.Item(i) is slow for folders with large
  // child item counts, so we use Declares on Windows instead.
  // Adapted from Aaron Ballman - see http://tinyurl.com/5susum
  
  Soft Declare Function FindFirstFileA Lib "Kernel32" (path as CString, data as Ptr) as Integer
  Soft Declare Function FindFirstFileW Lib "Kernel32" (path as WString, data as Ptr) as Integer
  Soft Declare Function FindNextFileA Lib "Kernel32" (handle as Integer, data as Ptr) as Boolean
  Soft Declare Function FindNextFileW Lib "Kernel32" (handle as Integer, data as Ptr) as Boolean
  Declare Sub FindClose Lib "Kernel32" (handle as Integer)
  
  dim UnicodeIsAvailable as boolean = System.IsFunctionAvailable("FindFirstFileW", "Kernel32")
  
  dim ChildData as MemoryBlock // WIN32_FIND_DATA struct
  dim ChildHandle as integer
  
  if UnicodeIsAvailable then
    
    ChildData = new MemoryBlock(592)
    ChildHandle = FindFirstFileW(f.AbsolutePath + "*.*", ChildData)
    
  else
    
    ChildData = new MemoryBlock(318)
    ChildHandle = FindFirstFileA(f.AbsolutePath + "*.*", ChildData)
    
  end if
  
  if ChildHandle <> -1 then
    
    dim ChildAttrs as UInt32 // first 4 bytes of WIN32_FIND_DATA
    dim ChildName as string
    
    // Loop through remaining items in the folder.
    
    dim FoundNextChild as Boolean
    
    do // loop through remaining children
      
      ChildAttrs = ChildData.UInt32Value(0)
      const NameOffset = 44
      
      if UnicodeIsAvailable then
        
        ChildName = ChildData.WString(NameOffset)
        FoundNextChild = FindNextFileW(ChildHandle, ChildData)
        
      else
        
        ChildName = ChildData.CString(NameOffset)
        FoundNextChild = FindNextFileA(ChildHandle, ChildData)
        
      end if
      
      // Now that we have its name and attributes, we can decide
      // whether this child should be added to our return array.
      
      dim ChildIsFolder as boolean = (ChildAttrs and UInt32(16)) <> 0
      
      if (ReturnFileNames and not ChildIsFolder) or _
        (ReturnFolderNames and ChildIsFolder) then
        
        if childName <> "." and childName <> ".." then
          result.Append(ChildName)
        end if
        
      end if
      
    loop until not FoundNextChild // should really test GetLastError for ERROR_NO_MORE_FILES
    
    FindClose ChildHandle
    
  end if
  
#else
  
  // On non-Windows systems, pure RB code seems pretty fast.
  
  dim child as FolderItem, ub as Integer = F.Count
  
  for i as integer = 1 to ub
    
    child = f.TrueItem(i)
    
    if (ReturnFileNames and not Child.Directory) or _
      (ReturnFolderNames and Child.Directory) then
      result.Append child.Name
    end if
    
  next i
  
#endif

end if

return result

End Function[/code]