Delphi everything、光速搜索代码,GetFullFileName得优化  
官方Delphi 学习QQ群: 682628230(三千人)
频道

Delphi everything、光速搜索代码,GetFullFileName得优化


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


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


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


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


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


{ 获取文件全路径,包含路径和文件名 }

procedure GetFullFileName(var FileList: TStringList; const chrLogiclDiskName: Char; const bSort: Boolean = False);

var

  UInt64DirList    : TArray;

  III              : Integer;

  UPID             : UInt64;

  intIndex         : Integer;

  dirList          : TStringList;

  intDirectoryCount: Integer;

begin

  { 将 FileList 按 FileReferenceNumber 数值排序 }

  FileList.Sorted := False;

  FileList.CustomSort(Int64Sort);

 

  { 先处理目录,获取路径的全路径名称 }

  dirList := TStringList.Create;

  try

    { 获取目录的总数 }

    intDirectoryCount := 0;

    for III           := 0 to FileList.Count - 1 do

    begin

      if PFileInfo(FileList.Objects[III])^.bDirectory then

      begin

        Inc(intDirectoryCount);

      end;

    end;

    SetLength(UInt64DirList, intDirectoryCount);

 

    { 将所有目录信息添加到目录列表 }

    intDirectoryCount := 0;

    for III           := 0 to FileList.Count - 1 do

    begin

      if PFileInfo(FileList.Objects[III])^.bDirectory then

      begin

        dirList.AddObject(PFileInfo(FileList.Objects[III])^.strFileName, FileList.Objects[III]);

        UInt64DirList[intDirectoryCount] := PFileInfo(FileList.Objects[III])^.FileReferenceNumber;

        Inc(intDirectoryCount);

      end;

    end;

 

    { 获取目录的全路径名称 }

    intDirectoryCount := 0;

    for III           := 0 to FileList.Count - 1 do

    begin

      if PFileInfo(FileList.Objects[III])^.bDirectory then

      begin

        UPID := PFileInfo(FileList.Objects[III])^.ParentFileReferenceNumber;

        while TArray.BinarySearch(UInt64DirList, UPID, intIndex) do

        begin

          UPID                  := PFileInfo(dirList.Objects[intIndex])^.ParentFileReferenceNumber;

          FileList.Strings[III] := PFileInfo(dirList.Objects[intIndex])^.strFileName + '\' + FileList.Strings[III];

        end;

        FileList.Strings[III]              := (chrLogiclDiskName + ':\' + FileList.Strings[III]);

        dirList.Strings[intDirectoryCount] := FileList.Strings[III];

        Inc(intDirectoryCount);

      end;

    end;

 

    { 再获取每个文件的全路径 }

    for III := 0 to FileList.Count - 1 do

    begin

      if not PFileInfo(FileList.Objects[III])^.bDirectory then

      begin

        UPID := PFileInfo(FileList.Objects[III])^.ParentFileReferenceNumber;

        if TArray.BinarySearch(UInt64DirList, UPID, intIndex) then

        begin

          FileList.Strings[III] := dirList.Strings[intIndex] + '\' + FileList.Strings[III];

        end

        else

        begin

          FileList.Strings[III] := chrLogiclDiskName + '\' + FileList.Strings[III];

        end;

      end;

    end;

 

    { 将所有文件按文件名排序 }

    if bSort then

      FileList.Sort;

  finally

    dirList.Free;

  end;

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;


源码:https://github.com/dbyoung720/PBox/tree/master/module/uFiles

————————————————


原文链接:https://blog.csdn.net/dbyoung/article/details/80077154



推荐分享
图文皆来源于网络,内容仅做公益性分享,版权归原作者所有,如有侵权请告知删除!
 

Copyright © 2014 DelphiW.com 开发 源码 文档 技巧 All Rights Reserved
晋ICP备14006235号-8 晋公网安备 14108102000087号

执行时间: 0.036130905151367 seconds