2011-04-15 46 views
14

我将参数值'*1.dat'传递给FindFirst,仍然是FindFirst()例程返回的第一个文件是46checks5.dat,它非常一致。为什么FindFirst返回与掩码不匹配的文件名?

这是一个已知的问题?

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; 

回答

23

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

可以容易地再现在一个空的目录在命令提示相同的行为:

 
C:\TEMP>echo. > 46checks5.dat 
C:\TEMP>dir /x *1.dat 
Volume in drive C has no label. 
Volume Serial Number is 5C09-D9DE 

Directory of C:\TEMP 

2011.04.15 21:37     3 46CHEC~1.DAT 46checks5.dat 
       1 File(s)    3 bytes 

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

搜索包括多长和短的 文件名。

要解决此问题,请使用Delphi的封装器FindFirstFile()来调用Win32 API FindFirstFileEx()。通过FindExInfoBasicfInfoLevelId参数。

0

您还有其他错误。

我创建了一个文件夹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,正如我所期望的。

+0

我创建了三个文件(461checksa1.dat,46checks1.dat,46checksa1.dat,46checks5.dat)并使用您的代码,每个文件都显示在备忘录中,包括最后一个没有'1'在文件名中! – 2011-04-15 17:43:48

+0

对不起,我的意思是我创建了四个文件(其中一个在名称中缺少'1') – 2011-04-15 17:48:41

相关问题