方案1:
您会非常失望,因为根据文件放入目录结构的顺序,文件的删除会导致FindNext跳过匹配的现有文件,因此您最终将不会删除所有想要的文件。您要做的是设置要删除的列表。然后,一旦设置了列表,便可以将其删除。
注意:请注意,许多人认为您要做的就是建立列表然后删除它们。这不是真的。有许多文件可以设置只读/只读属性等。因此,您必须先清除此文件,否则删除将失败。因此,如果您在我的例程中注意到,我会清除可能已为文件设置的所有属性。这是一个例子:
procedure DeleteTempRAW(S1: String);
var
SearchRec: TSearchRec;
X: Integer;
Path: String;
ListToDelete: TStringList;
Ok: Boolean;
begin
ListToDelete := TStringList.Create;
Path := ExtractFilePath(S1);
X := FindFirst(S1, faAnyFile - faDirectory - faVolumeID, SearchRec);
if X = 0 then
begin
while X = 0 do
begin
ListToDelete.Add(Path + SearchRec.Name);
X := FindNext(SearchRec);
end;
FindClose(SearchRec);
end;
for X := 0 to ListToDelete.Count - 1 do
begin
FileSetAttr(ListToDelete[X], 0);
DeleteFile(ListToDelete[X]);
end;
ListToDelete.Free;
end;
You would call it like so: DeleteTempRaw('C:\TEMP\MASTER*.*');
Tip by Anon.
方案2
首先,在列表中填写要删除的文件名。这是一个通用的功能。给定一个路径(APath)和文件掩码(AMASK),则直接将填补ALIST相匹配的所有文件的完整路径AMASK。
procedure GetFiles(APath, AMask: string; AList: TStrings);
var
searchRec: SysUtils.TSearchRec;
begin
APath := IncludeTrailingBackslash(APath);
{Get all of the directories in this path}
if FindFirst(APath + '*.*', faDirectory, searchRec) = 0 then
repeat
with searchRec do
begin
if (Name <> '.') and (Name <> '..') then
if (Attr and faDirectory > 0) then
GetFiles(APath + Name, AMask, AList);
end;
Application.ProcessMessages;
until
FindNext(searchRec) <> 0;
SysUtils.FindClose(searchRec);
{Get all of the files in this directory which match the file mask}
if FindFirst(APath + AMask, faAnyFile, searchRec) = 0 then
repeat
with searchRec do
begin
if (Name <> '.') and (Name <> '..') then
if (Attr and faDirectory <= 0) then
AList.Add(APath + searchRec.Name);
end;
Application.ProcessMessages;
until
FindNext(searchRec) <> 0;
SysUtils.FindClose(searchRec);
end;
这是使用例程的方法
var
MyFileList: TStringList;
iCnt: integer;
begin
MyFileList := nil;
try
MyFileList := TStringList.Create;
{Get all files in C:\ and its subdirectories that match "Master*."
(the period with nothing after it only looks for files with no extension)}
GetFiles('c:\', 'Master*.', MyFileList);
{Go through each file in the list and delete it}
for iCnt := 0 to MyFileList.Count - 1 do
bRet := DeleteFile(MyFileList[iCnt]);
finally
MyFileList.Free;
end;
end;
Tip by Anon.
方案3
解决此问题的经典方法是使用FindFirst / FindNext / FindClose循环在目标目录中查找文件,并在找到文件时将其删除,如下所示:
procedure DeleteFilesWithWildCard(Dir, Prefix, Suffix: String);
var
SRec: TSearchRec;
begin
{ Check the passed parameter, make sure it ends in a backslash }
if Length(Dir) = 0 then
Exit;
if Directory[Length(Dir)] <> '\' then
AppendStr(Dir, '\' );
if FindFirst(Dir + Prefix + '*.' + Suffix, faAnyfile, SRec ) = 0 then
try
{ We must call FindClose after the FindFirst succeeded, otherwise
the program looses a system handle. So use a try finally block. }
repeat
{ We have a hit. Check if it is a directory }
if ( faDirectory and SRec.Attr ) = 0 then
begin
{ It is a file, try to delete it. This may fail if the file
has the read-only attribute. If it does we show a message but
continue with other files if the user does not abort. }
if not SysUtils.DeleteFile(Dir + SRec.Name ) then
begin
if MessageDlg(
'Cannot delete ' + SRec.Name +
', the file may be read-only. Do you want to abort the ' +
'operation?',
mtError,
[mbYes, mbNo, mbCancel],
0
) <> mrNo then
SysUtils.Abort;
end;
end;
{ Done with this hit, search for the next one. }
until
FindNext(SRec) <> 0;
finally
FindClose( SRec );
end;
end;