2011-04-15 90 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

相關問題