Delphi 版 everything、光速搜索代码》,文章中关于获取文件全路径的函数:GetFullFileName,有一个地方值得优化。
就是有多个文件,它们可能属于同一个目录。
譬如 System32 目录下有2000多个文件,GetFullFileName 还是进行了2000多次的查询,效率肯定是受影响的。
先处理目录,获取目录全路径名称。
然后文件只用查询一次,就知道它的父路径的全路径了。效率肯定会提高的。尝试了一下。
- procedure?GetFullFileName(var?FileList:?TStringList;?const?chrLogiclDiskName:?Char;?const?bSort:?Boolean?=?False);??
- var??
- ??UInt64DirList????:?TArray<UInt64>;??
- ??III??????????????:?Integer;??
- ??UPID?????????????:?UInt64;??
- ??intIndex?????????:?Integer;??
- ??dirList??????????:?TStringList;??
- ??intDirectoryCount:?Integer;??
- begin??
- ??
- ??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,?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;