繁体   English   中英

在Delphi中查找编号最大的文件的有效方法

[英]Efficient way to find file with highest number in Delphi

我有一个具有固定模式(CONST_)和运行编号(XXXX)的文件,例如: CONST_XXXX.XYZ

我正在寻找一种有效的方法来获取Delphi中编号最高的文件。 如果有很多文件,使用FindFirst / FindNext遍历似乎效率很低。

众所周知,找到列表的最大值通常需要检查所有项目。 而且我相信最有效的方法是使用FindFirstFile/FindNextFile或相关的API。 很难想象会有任何真正的方法来改进用于枚举文件的官方系统API。

这肯定是这里提供的意见: 用C ++枚举文件夹是否比FindFirstFile / FindNextFile更快? 请注意,我不接受手动分析文件系统的选项。 我认为这不太实用。

另一方面,该答案希望带有FindExInfoBasicFIND_FIRST_EX_LARGE_FETCH FindFirstFileEx可能会比普通的FindFirstFile产生更好的性能。

您可能需要寻找一种替代解决方案,该解决方案不涉及对文件满目录的重复枚举。 也许使用数据库,以便您可以利用索引。 实际上,内置索引服务可能有用。

这样的事情怎么样:

for I := 0 to MAX_DIGITS - 4
begin
    S := 'CONST_' + StringOfChar('0', I);
    for C := '9' downto '1' do
    begin
      if FindFirst(S + C + '*.XYZ', faAnyFile, SearchResult) = 0 then
      begin
          //Code to iterate through the results using FindNext 
          //and returning "biggest" Name
          Result := SearchResult.FileName
          while FindNext(SearchResult) = 0 
            //ommitted: handling dirs / hidden
            if CompareStr(Result, SearchResult.FileName) < 0 then
              Result := SearchResult.FileName;
          //adding recursion instead of while... should make it even faster
          FindClose(SearchResult);
          Break;
      end; 
    end;
end;

警告:此代码尚未经过测试

一个替代方案是

for I := 9999 downto 0 do
  begin
  FileName := Format ('CONST_%.4d.XYZ', [I]);
  if FileExists(FileName) then
    Break;
  end;  

是否更快,取决于您期望的数字以及FileExistsFindFirst的性能,我无法对此发表评论。

另一种方法是将所有发生的CONST_*.XYZ 。XYZ读取到FileListBox中,然后显示最后一个。

procedure TForm1.Button1Click(Sender: TObject);
begin
FileListBox1.Directory:='D:\samples';
FileListBox1.Mask:='CONST_*.XYZ';
FileListBox1.Update;
Label1.Caption:= FileListBox1.Items[FileListBox1.Items.Count-1];
end;

为了使其更快,您可以使用一个函数

function getRegion(filestr:string):Boolean;
begin
  if FindFirst(filestr, faAnyFile, searchResult) = 0 then result:=true else result:=false;
  if result then begin
     findN:=filestr;
  end;
end;

begin

SetCurrentDir('D:\samples');
  for i:=9 downto 0 do begin
    if getRegion(Format ('CONST_%.1d*.XYZ', [i])) then break;
  end;

FileListBox1.Directory:='D:\samples';
FileListBox1.Mask:=findN;
FileListBox1.Update;
Label1.Caption:= FileListBox1.Items[FileListBox1.Items.Count-1];

更新资料
对于测试A),文件是从0000-4999创建的
对于测试B)文件是从0000-9999创建的
由于用户jpfollenius使用downto TestA制作的文件从0000到只有4999

00004999 = 5000个文件
9999降到4999 = 5000个文件

在此处输入图片说明

测试台TestA

在此处输入图片说明

测试B

我可以容纳更多文件50000个文件,我的解决方案可以加载10000个文件名
例如5 0000到5 9999

  • moskito-x .................................. 0.345秒(已测试)
  • 纯FindFirst / FindNext ..... 0.390秒估计为(0.039 * 10)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM