[转载]《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<UInt64>;
- 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;
[转载]《Delphi 版 everything、光速搜索代码》 关于获取文件全路径 GetFullFileName 函数的优化的更多相关文章
- [转载]Delphi 版 everything、光速搜索代码
近日没啥事情,研究了一下 everything.光速搜索原理.花了一个礼拜时间,终于搞定. 废话不多说,直接上代码: unit uMFTSearchFile; { dbyoung@sina.com 2 ...
- Delphi获取文件名、文件名不带扩展名、文件名的方法;delphi 获取文件所在路径
取文件名 ExtractFileName(FileName); 取文件扩展名: ExtractFileExt(filename); 取文件名,不带扩展名: 方法一: Function Extrac ...
- java版ftp简易客户端(可以获取文件的名称及文件大小)
java版ftp简易客户端(可以获取文件的名称及文件大小) package com.ccb.ftp; import java.io.IOException; import java.net.Socke ...
- 教程-Delphi中的GExperts搜索代码快捷键
Shift+Ait+S 打开搜索 Ctrl+Ait+R 打开上次搜索结果
- delphi根据进程PID获取程序所在路径的函数(用OpenProcess取得句柄,用GetModuleFileNameEx取得程序名)
uses psapi; {根据进程PID获取程序所在路径的函数}function GetProcessExePath(PID: Cardinal): string;varpHandle: THandl ...
- 拖放获取文件信息的bat代码
参考:岁月如歌-通过拖曳获取文件信息的bat代码 拖放获取文件信息的bat代码 使用命令行配合7z解压文件时由于每次解压的文件不同,因此搜索了一下拖放识别文件信息的方法,以此方式来减轻工作量 获取文件 ...
- Delphi获取文件名、不带扩展名文件名、文件所在路径、上级文件夹路径的方法
1.获取不带扩展名的文件名方法,利用ChangeFileExt函数修改传入参数的扩展为空,并不会对文件本身产生变更. ChangeFileExt(ExtractFileName('D:\KK\Test ...
- 通过崩溃地址找错误行数之Delphi版
通过崩溃地址找错误行数之Delphi版2009-5-11 17:42:35 来源: 转载 作者:网络 访问:360 次 被顶:2 次 字号:[大 中 小]核心提示:什么是 MAP 文件?简单地讲, M ...
- 雪花算法(snowflake)delphi版
雪花算法简单描述: + 最高位是符号位,始终为0,不可用. + 41位的时间序列,精确到毫秒级,41位的长度可以使用69年.时间位还有一个很重要的作用是可以根据时间进行排序. + 10位的机器标识,1 ...
随机推荐
- MiCode 40: 找小“3”
题目链接 这道题真的是zjb恶心, 看其起来像是个数位dp, 然而我并不会数位dp.然后就xjb乱写了个雷类似于动态规划的玩意, 然后调出了\(9\times 9 = 81\)种Bug, 终于过了. ...
- linux命令(1):sed命令
实例一: Config_file文件内容如下: sed去除注释行:sed -i -c -e '/^#/d' config_file [会删除指定文件带有注释行] sed去除空行: sed -i -c ...
- 《逐梦旅程 WINDOWS游戏编程之从零开始》笔记10——三维天空的构建&三维粒子的实现&多游戏模型的载入
第23章 三维天空的构建 目前描述三维天空的技术主要包括三种类型,直接来介绍使用最广泛的模拟技术,详细的描述可以见作者的博文. 天空盒(Sky Box),即放到场景的是一个立方体.它是目前使用最广泛的 ...
- scrapy-redis组件的使用
scrapy-redis是一个基于redis的scrapy组件,通过它可以快速实现简单分布式爬虫程序,该组件本质上提供了三大功能: scheduler - 调度器 dupefilter - URL去重 ...
- Prometheus exporter的Node exporter是可以独立安装,用来测试的
现在慢慢在把prometheus operator的一些概念组织完整. https://github.com/coreos/prometheus-operator/tree/master/contri ...
- cookie笔记(二)
小荔枝 增 删 查 改 <form action="javascript:void(0)" method="get" accept-charset=&qu ...
- python request post上传文件额外注意点
通用用法 但上图的字段名,类型需要根据不同接口填写,如某服务接口: 因而对应的上传代码如下: # 输出参数:请求响应报文import requestsrequest_url = 'https://XX ...
- js for循环的陷阱
☞问题概述 一页面有三个按钮,点击提示相应内容.相应内容已从后台获取,并转化成json数组. var content = ["提示1", "提示2", &quo ...
- zabbix报警-邮件-钉钉
安装zabbix的时候已经配置了zabbix_server的脚本目录 AlertScriptsPath=/opt/app/zabbix/script 所以把邮件.钉钉.微信相关的脚本都放在/opt/z ...
- java中byte取值范围为什么是 -128到127
概念:java中用补码表示二进制数,补码的最高位是符号位,最高位为“0”表示正数,最高位为“1”表示负数.正数补码为其本身:负数补码为其绝对值各位取反加1:例如:+21,其二进制表示形式是000101 ...