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

时间:2014-01-30 13:07:15

标签: delphi delphi-2006

我有一个固定模式(CONST_)和正在运行的数字(XXXX)的文件,如下所示:CONST_XXXX.XYZ

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

4 个答案:

答案 0 :(得分:3)

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

这肯定是这里提供的意见:Is there a faster alternative to enumerating folders than FindFirstFile/FindNextFile with C++?请注意,我拒绝手动解析文件系统的选项。我不认为这是非常实际的。

另一方面,这个answer提供了FindFirstFileEx FindExInfoBasicFIND_FIRST_EX_LARGE_FETCH可能比普通FindFirstFile更好的表现。

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

答案 1 :(得分:2)

这样的事情怎么样:

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;

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

答案 2 :(得分:-1)

另一种选择是

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

这是否更快取决于您所期望的数字以及我无法评论的FileExistsFindFirst的效果。

答案 3 :(得分:-1)

另一种方法是将所有发生的CONST_*.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
创建的 TestA将文件从0000生成到4999,因为用户jpfollenius使用了downto

00004999 = 5000个文件
来自9999 downto 4999 = 5000个文件

enter image description here

Testtable TestA

enter image description here

测试B

我有更多文件50000文件,我的解决方案加载10000个文件名
例如5 0000到5 9999需要

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