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

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

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

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

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

  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. dirList := TStringList.Create;
  16. try
  17. { 获取目录的总数 }
  18. intDirectoryCount := 0;
  19. for III           := 0 to FileList.Count - 1 do
  20. begin
  21. if PFileInfo(FileList.Objects[III])^.bDirectory then
  22. begin
  23. Inc(intDirectoryCount);
  24. end;
  25. end;
  26. SetLength(UInt64DirList, intDirectoryCount);
  27. { 将所有目录信息添加到目录列表 }
  28. intDirectoryCount := 0;
  29. for III           := 0 to FileList.Count - 1 do
  30. begin
  31. if PFileInfo(FileList.Objects[III])^.bDirectory then
  32. begin
  33. dirList.AddObject(PFileInfo(FileList.Objects[III])^.strFileName, FileList.Objects[III]);
  34. UInt64DirList[intDirectoryCount] := PFileInfo(FileList.Objects[III])^.FileReferenceNumber;
  35. Inc(intDirectoryCount);
  36. end;
  37. end;
  38. { 获取目录的全路径名称 }
  39. intDirectoryCount := 0;
  40. for III           := 0 to FileList.Count - 1 do
  41. begin
  42. if PFileInfo(FileList.Objects[III])^.bDirectory then
  43. begin
  44. UPID := PFileInfo(FileList.Objects[III])^.ParentFileReferenceNumber;
  45. while TArray.BinarySearch(UInt64DirList, UPID, intIndex) do
  46. begin
  47. UPID                  := PFileInfo(dirList.Objects[intIndex])^.ParentFileReferenceNumber;
  48. FileList.Strings[III] := PFileInfo(dirList.Objects[intIndex])^.strFileName + '\' + FileList.Strings[III];
  49. end;
  50. FileList.Strings[III]              := (chrLogiclDiskName + ':\' + FileList.Strings[III]);
  51. dirList.Strings[intDirectoryCount] := FileList.Strings[III];
  52. Inc(intDirectoryCount);
  53. end;
  54. end;
  55. { 再获取每个文件的全路径 }
  56. for III := 0 to FileList.Count - 1 do
  57. begin
  58. if not PFileInfo(FileList.Objects[III])^.bDirectory then
  59. begin
  60. UPID := PFileInfo(FileList.Objects[III])^.ParentFileReferenceNumber;
  61. if TArray.BinarySearch(UInt64DirList, UPID, intIndex) then
  62. begin
  63. FileList.Strings[III] := dirList.Strings[intIndex] + '\' + FileList.Strings[III];
  64. end
  65. else
  66. begin
  67. FileList.Strings[III] := chrLogiclDiskName + '\' + FileList.Strings[III];
  68. end;
  69. end;
  70. end;
  71. { 将所有文件按文件名排序 }
  72. if bSort then
  73. FileList.Sort;
  74. finally
  75. dirList.Free;
  76. end;
  77. 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;

最新文章

  1. java并发编程(八)多线程环境下安全使用集合
  2. Unity官网教程之Tips
  3. css选择器(E[att^=”val”]序号选择器)
  4. MapReduce、Hbase接口API实践
  5. 算法中的增长率(Rate of Growth)是什么意思?
  6. 9、Cocos2dx 3.0游戏开发三查找值小工厂方法模式和对象
  7. Swift: 打造滑动解锁文字动画
  8. .Net IOC框架入门之二 CastleWindsor
  9. UVA - 11624 多点bfs [kuangbin带你飞]专题一
  10. 不用代码就能实现get与post
  11. python之数据类型详解
  12. Git的初步学习
  13. 【AtCoder】ARC077
  14. Calculate CAN bit timing parameters -- STM32
  15. JDK1.5新特性,基础类库篇,浅谈并发工具包(Concurrency Utilities)
  16. 【TCP/IP详解 卷一:协议】第一章概论 学习笔记
  17. hadoop群集 启动
  18. AtCoder | ARC102 | 瞎讲报告
  19. react 项目微信端 签名失败 原因
  20. centos7 docker 使用pipework 做虚拟机

热门文章

  1. 8:django sessions(会话)
  2. AC日记——【模板】分块/带修改莫队(数颜色) 洛谷 P1903
  3. [Bootstrap]modal弹出框
  4. slice切割数组arr=[[0,1],[2,3]]
  5. sublime text光标移入移出括号的快捷键设置
  6. Vue生命周期总结
  7. python socket 超时设置 errno10054
  8. gcc、make、makefile、cmake、cmakelists区别
  9. cookies和session区别
  10. HDU5742 It&#39;s All In The Mind 数学思维题