[转载]《Delphi 版 everything、光速搜索代码》 关于获取文件全路径 GetFullFileName 函数的优化

Delphi 版 everything、光速搜索代码》,文章中关于获取文件全路径的函数:GetFullFileName,有一个地方值得优化。

就是有多个文件,它们可能属于同一个目录。

譬如 System32 目录下有2000多个文件,GetFullFileName 还是进行了2000多次的查询,效率肯定是受影响的。

先处理目录,获取目录全路径名称。

然后文件只用查询一次,就知道它的父路径的全路径了。效率肯定会提高的。尝试了一下。

[delphi] view plain copy
 
  1. { 获取文件全路径,包含路径和文件名 }  
  2. procedure GetFullFileName(var FileList: TStringList; const chrLogiclDiskName: Char; const bSort: Boolean = False);  
  3. var  
  4.   UInt64DirList    : TArray<UInt64>;  
  5.   III              : Integer;  
  6.   UPID             : UInt64;  
  7.   intIndex         : Integer;  
  8.   dirList          : TStringList;  
  9.   intDirectoryCount: Integer;  
  10. begin  
  11.   { 将 FileList 按 FileReferenceNumber 数值排序 }  
  12.   FileList.Sorted := False;  
  13.   FileList.CustomSort(Int64Sort);  
  14.   
  15.   { 先处理目录,获取路径的全路径名称 }  
  16.   dirList := TStringList.Create;  
  17.   try  
  18.     { 获取目录的总数 }  
  19.     intDirectoryCount := 0;  
  20.     for III           := to FileList.Count - do  
  21.     begin  
  22.       if PFileInfo(FileList.Objects[III])^.bDirectory then  
  23.       begin  
  24.         Inc(intDirectoryCount);  
  25.       end;  
  26.     end;  
  27.     SetLength(UInt64DirList, intDirectoryCount);  
  28.   
  29.     { 将所有目录信息添加到目录列表 }  
  30.     intDirectoryCount := 0;  
  31.     for III           := to FileList.Count - do  
  32.     begin  
  33.       if PFileInfo(FileList.Objects[III])^.bDirectory then  
  34.       begin  
  35.         dirList.AddObject(PFileInfo(FileList.Objects[III])^.strFileName, FileList.Objects[III]);  
  36.         UInt64DirList[intDirectoryCount] := PFileInfo(FileList.Objects[III])^.FileReferenceNumber;  
  37.         Inc(intDirectoryCount);  
  38.       end;  
  39.     end;  
  40.   
  41.     { 获取目录的全路径名称 }  
  42.     intDirectoryCount := 0;  
  43.     for III           := to FileList.Count - do  
  44.     begin  
  45.       if PFileInfo(FileList.Objects[III])^.bDirectory then  
  46.       begin  
  47.         UPID := PFileInfo(FileList.Objects[III])^.ParentFileReferenceNumber;  
  48.         while TArray.BinarySearch(UInt64DirList, UPID, intIndex) do  
  49.         begin  
  50.           UPID                  := PFileInfo(dirList.Objects[intIndex])^.ParentFileReferenceNumber;  
  51.           FileList.Strings[III] := PFileInfo(dirList.Objects[intIndex])^.strFileName + '\' + FileList.Strings[III];  
  52.         end;  
  53.         FileList.Strings[III]              := (chrLogiclDiskName + ':\' + FileList.Strings[III]);  
  54.         dirList.Strings[intDirectoryCount] := FileList.Strings[III];  
  55.         Inc(intDirectoryCount);  
  56.       end;  
  57.     end;  
  58.   
  59.     { 再获取每个文件的全路径 }  
  60.     for III := to FileList.Count - do  
  61.     begin  
  62.       if not PFileInfo(FileList.Objects[III])^.bDirectory then  
  63.       begin  
  64.         UPID := PFileInfo(FileList.Objects[III])^.ParentFileReferenceNumber;  
  65.         if TArray.BinarySearch(UInt64DirList, UPID, intIndex) then  
  66.         begin  
  67.           FileList.Strings[III] := dirList.Strings[intIndex] + '\' + FileList.Strings[III];  
  68.         end  
  69.         else  
  70.         begin  
  71.           FileList.Strings[III] := chrLogiclDiskName + '\' + FileList.Strings[III];  
  72.         end;  
  73.       end;  
  74.     end;  
  75.   
  76.     { 将所有文件按文件名排序 }  
  77.     if bSort then  
  78.       FileList.Sort;  
  79.   finally  
  80.     dirList.Free;  
  81.   end;  
  82. end;  

这个函数比原来的函数效率上刚好提高了一倍。

100万个的文件,耗时4秒左右。200万个的文件,耗时8秒左右。

 

 

注:原有的  TFileInfo 添加个目录属性:

  TFileInfo = record
    strFileName: String;               // 文件名称
    bDirectory: Boolean;               // 是否是目录 <增加>
    FileReferenceNumber: UInt64;       // 文件的ID
    ParentFileReferenceNumber: UInt64; // 文件的父ID

  end;

在代码 

FileList.AddObject(strFileName, TObject(pfi)); 

前,添加一行:

pfi^.bDirectory  := UsnRecord^.FileAttributes and FILE_ATTRIBUTE_DIRECTORY = FILE_ATTRIBUTE_DIRECTORY;

posted @ 2018-06-25 08:30  h2z  阅读(422)  评论(0编辑  收藏  举报