Delphi 递归删除文件并跳过正在使用的文件?
我正在使用Windows API递归删除许多文件和文件夹。我在没有UI的情况下使用它并抑制错误。问题是,如果其中一个文件正在使用,它将完全失败。我期待这种可能性,并希望这种情况继续下去,跳过任何这样的情况。失败的一个文件实际上是调用此删除命令的同一个EXE(无论如何,在所有操作完成后将删除该命令) 以下是我现在正在做的:Delphi 递归删除文件并跳过正在使用的文件?,delphi,winapi,shfileoperation,Delphi,Winapi,Shfileoperation,我正在使用Windows API递归删除许多文件和文件夹。我在没有UI的情况下使用它并抑制错误。问题是,如果其中一个文件正在使用,它将完全失败。我期待这种可能性,并希望这种情况继续下去,跳过任何这样的情况。失败的一个文件实际上是调用此删除命令的同一个EXE(无论如何,在所有操作完成后将删除该命令) 以下是我现在正在做的: procedure DeleteDirectory(const DirName: string); var FileOp: TSHFileOpStruct; begin
procedure DeleteDirectory(const DirName: string);
var
FileOp: TSHFileOpStruct;
begin
FillChar(FileOp, SizeOf(FileOp), 0);
FileOp.wFunc := FO_DELETE;
FileOp.pFrom := PChar(DirName+#0);//double zero-terminated
FileOp.fFlags := FOF_SILENT or FOF_NOERRORUI or FOF_NOCONFIRMATION;
SHFileOperation(FileOp);
end;
如何使其跳过文件正在使用的任何事件?我查看了,但找不到任何可以做到这一点的方法。以下是您可以在函数中实现的一个想法,以验证是否有任何文件正在使用:
function IsFileInUse(FileName: TFileName): Boolean;
var
HFileRes: HFILE;
begin
Result := False;
if not FileExists(FileName) then
Exit;
HFileRes := CreateFile(PChar(FileName),
GENERIC_READ or GENERIC_WRITE,
0,
nil,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
0);
Result := (HFileRes = INVALID_HANDLE_VALUE);
if not Result then
CloseHandle(HFileRes);
end;
也许它可以帮助你。你为什么不试试这个:
procedure DeleteFiles(const DirName: String);
var
SR: TSearchRec;
i: Integer;
begin
//get all files in directory
i := FindFirst(DirName +'\*.*', faAnyFile, SR);
while i = 0 do
begin
if (SR.Attr and faDirectory) <> faDirectory then
DeleteFile(DirName +'\'+ SR.Name);
i := FindNext(SR);
end;
FindClose(SR);
end;
过程删除文件(const DirName:String);
变量
SR:TSearchRec;
i:整数;
开始
//获取目录中的所有文件
i:=FindFirst(DirName+'\*.*',faAnyFile,SR);
当i=0时
开始
如果(高级属性和faDirectory)faDirectory,则
删除文件(DirName+'\'+SR.Name);
i:=FindNext(SR);
结束;
FindClose(SR);
结束;
这是另一种方法。
如果操作
可以处理这个问题。你可能需要使用它,或者使用递归FindFirst,FindNext方法自己遍历目录。你应该发布显示问题的代码…而不是有效的代码!!@Jochenkambach你读了我的问题吗?@Jerry我回答中的第二个代码示例将做您需要的事情:我认为这是IFileOperation或手动树漫游这将如何与调用SHFileOperation
交互?我以不同的方式使用它。我在目录中的所有文件中使用循环,然后在删除它之前检查当前文件是否正在使用。正如我所说的,这只是一个想法。在这种情况下,您只需调用D即可eleteFile
并忽略返回值。如果无法删除该文件,则不会删除该文件,并且DeleteFile
将返回true。像这样进行二次猜测是毫无意义的。是的,调用DeleteFile
是正确的方法。调用CreateFile
也将修改上次访问时间,这不是预期的…并且即使CreateFile
成功,它也可能在DeleteFile
中失败。No-1,但这并不能解决我正在做的事情。最后,没有必要进行此检查,因为Windows会自动失败。问题是,使用我的方法,我无法想出如何让它继续自动删除所有其他内容并跳过所有正在使用的东西。因为它不是递归的。令人惊讶的是,*.
仍然存在。只要*
就足够了。