【问题标题】:Why does FindFirst return file names that don't match the mask?为什么 FindFirst 返回与掩码不匹配的文件名?
【发布时间】:2011-04-15 16:35:54
【问题描述】:

我将参数值'*1.dat' 传递给FindFirst,仍然是FindFirst() 例程返回的第一个文件是46checks5.dat,非常一致。

这是一个已知问题吗?

vpath:=trim(vpath);
result:=true;
try
  res:=findfirst(vpath+'\'+vmask,faarchive,search);    //vmask = *1.dat
  try 
    while res=0 do
    begin
      vlist.add(search.name);   //searchname returned is 46checks5.dat!!!
      res:=findnext(search);
    end;
  finally
    findclose(search);
  end;
except
  result:=false;
end;

【问题讨论】:

    标签: delphi findfirst


    【解决方案1】:

    原因是文件有一个“长”的名称,即超过 8 个字符。对于此类文件,Windows 还会创建“短”名称,通常以longna~1.dat 的形式创建,并且可以通过*1.dat 通配符找到该短名称。

    您可以在空目录中的命令提示符下轻松重现相同的行为:

    C:\TEMP>回声。 > 46checks5.dat C:\TEMP>dir /x *1.dat 驱动器 C 中的卷没有标签。 卷序列号为 5C09-D9DE C:\TEMP 目录 2011.04.15 21:37 3 46CHEC~1.DAT 46checks5.dat 1 个文件 3 个字节

    FindFirstFile() 的文档,这是 FindFirst 的底层 API 状态:

    搜索包括多头和空头 文件名。

    要解决此问题,请调用 Win32 API FindFirstFileEx(),而不是使用 Delphi 的包装器到 FindFirstFile()。将FindExInfoBasic 传递给fInfoLevelId 参数。

    【讨论】:

    • 是的,我在这里看到:blog.excastle.com/2007/10/01/… 但是,这并不能解决我的问题。是否有解决此问题的方法、变通方法或替代解决方案?
    • @user 我冒昧地将解决方法添加到答案中。
    • 谢谢大卫,我会测试一下
    • +1。不错的收获。不过,我不确定为什么我的代码没有同样的问题。
    • 注意:由于各种其他原因,文件可能具有“长”名称,例如它可能包含多个句点、空格或某些其他字符,或者具有超过 3 个字符的扩展名。特别是,后者意味着带有“.data”等扩展名的文件也将被赋予一个单独的短名称,例如"FILE~1.DAT",它也将匹配 *.dat 通配符。
    【解决方案2】:

    你还有其他问题。

    我创建了一个文件夹C:\Temp\Test,在里面放了三个文件:

    TestFile1.txt
    TestFile2.txt
    TestFile3.txt
    

    然后我将TMemo 放在新项目的新空白表单上,并将此代码添加到“FormCreate”事件中:

    procedure TForm1.FormCreate(Sender: TObject);
    var
      sPath: string;
      sFile: string;
      SR: TSearchRec;
    begin
      sPath := 'C:\Temp\Test';
      sFile := '*1.txt';
    
      Memo1.Lines.Clear;
      if FindFirst(sPath + '\' + sFile, faArchive, SR) = 0 then
      begin
        try
          repeat
            Memo1.Lines.Add(SR.Name);
          until FindNext(SR) <> 0;
        finally
          FindClose(SR);
        end;
      end;
    end;
    

    当显示表单时,TMemo 只显示了一个文件,TestFile1.txt,正如我所期望的那样。

    【讨论】:

    • 我创建了三个文件(461checksa1.dat、46checks1.dat、46checksa1.dat、46checks5.dat)并使用您的代码,所有文件都显示在备忘录中,包括最后一个,文件名中没有“1”!
    • 抱歉,我的意思是我创建了四个文件(其中一个文件名中缺少一个“1”)
    • 正如我所说,你有问题。我刚刚复制了我现有的TestFile1.txt 以创建四个与您的名称相同的文件(包括扩展名),并修改了我的代码以查找*1.dat 而不是*1.txt。我在备忘录中列出了三个文件:461checksa1.dat, 46checks1.dat, and 46checksa1.dat。我的代码中唯一的更改是将sFile 变量中的扩展名从.txt 更改为.dat
    • 我怎么可能有什么问题。我创建了一个新项目,并使用了您上面的确切代码。我的表单,只有一个备忘录,我在 OnCreate 事件中使用了你的代码。
    猜你喜欢
    • 1970-01-01
    • 2020-05-29
    • 1970-01-01
    • 2020-10-19
    • 2015-02-01
    • 2019-10-11
    • 1970-01-01
    • 2018-06-12
    • 1970-01-01
    相关资源
    最近更新 更多