问题描述
我可以通过以下方法删除具有提供的路径的文件
I have the following method to delete a file with a provided path
private void DestroyFile(string path)
{
try
{
if (File.Exists(path))
{
File.Delete(path);
}
if (File.Exists(path))
{
throw new IOException(string.Format("Failed to delete file: '{0}'.", path));
}
}
catch (Exception ex)
{
throw ex;
}
}
如果文件存在于File.Delete方法之后,我将抛出IOException.具体地
I am getting the IOException that is thrown if the file exists after the File.Delete method. Specifically
我还确认执行完成后,该文件在path变量中的位置不存在.我想知道我是否在File.Delete之后更新文件系统与再次使用File.Exists对其进行检查之间的竞争条件下运行.有没有更好的方法可以顺利删除?我知道如果文件不存在,File.Delete不会返回错误,因此这些检查可能有点多余.我应该检查文件是否正在使用中,而不是根本不存在吗?
I have also confirmed that the file does not exist at the location in the path variable after the execution is complete. I am wondering if I am running up against a race condition between the file system updating after File.Delete and checking against it again with File.Exists. Is there a better way to smoothly delete? I know that File.Delete won't return an error if the file doesn't exist so maybe these checks are a bit redundant. Should I check if the file is in use rather than if it exists at all?
一些重要的附加信息:该程序可以并且确实可以成功运行,但是最近经常会看到此特定错误.
Some important additional information:The program can and does run successfully often but this particular error has been frequently seen recently.
推荐答案
File.Delete
将标记文件以删除.实际上,只有在关闭所有句柄的情况下,文件才真正被删除(如果没有这样的句柄-在File.Delete返回之后,它将始终被删除).如针对 DeleteFile winapi函数(由C#File.Delete
使用):
File.Delete
will mark file for deletion. File really will be deleted only when all handles to it are closed (if there are no such handles - it will always be deleted after File.Delete returns). As documented for DeleteFile winapi function (which is used by C# File.Delete
):
通常,没有删除文件的打开句柄.或者,如果有打开的句柄-它们通常没有删除"共享(此共享允许另一个进程将文件标记为删除),所以当您尝试删除此类文件时-它要么被删除(没有打开的句柄),要么拒绝访问或引发类似异常(某些句柄,但没有删除共享).
Usually there are no open handles to files you delete. Or, if there are open handles - they usually don't have "delete" share (this share allows another process to mark file for deletion), so when you try to delete such file - it either gets deleted (no open handles) or access denied or similar exception is thrown (some handles, but without delete share).
但是,有时某些软件(例如防病毒软件或搜索索引器)可能会打开具有删除"共享的任意文件,并将它们保留一段时间.如果您尝试删除此类文件-该文件将没有错误,并且在该软件关闭其句柄时实际上将删除该文件.但是,File.Exists
对于此类待删除"文件将返回true.
However, sometimes some software, such as antivirus or search indexer, might open arbitrary files with "delete" share and hold them for some time. If you try to delete such file - it will go without errors and file really will be deleted when that software closes its handle. However, File.Exists
will return true for such "pending delete" file.
您可以使用以下简单程序重现此问题:
You can reproduce this issue with this simple program:
public class Program {
public static void Main() {
string path = @"G:\tmp\so\tmp.file";
// create file with delete share and don't close handle
var file = new FileStream(path, FileMode.Create, FileAccess.ReadWrite, FileShare.Delete);
DestroyFile(path);
GC.KeepAlive(file);
}
private static void DestroyFile(string path) {
try {
if (File.Exists(path)) {
// no error
File.Delete(path);
}
// but still exists
if (File.Exists(path)) {
throw new IOException(string.Format("Failed to delete file: '{0}'.", path));
}
}
catch (Exception ex) {
throw ex;
}
}
}
您可以在上面的程序中再次尝试永久检查-该文件将一直存在,直到您关闭手柄为止.
You can retry File.Exists
check forever in the program above - file will exist until you close the handle.
这就是您遇到的情况-某些程序使用FileShare.Delete
对此文件打开了句柄.
So that's what happens in your case - some program has open handle to this file with FileShare.Delete
.
您应该预料到这种情况.例如-只需删除File.Exists
检查,因为您将文件标记为删除,并且该文件仍将被删除.
You should expect such situation. For example - just remove that File.Exists
check, since you marked file for deletion and it will be deleted anyway.
这篇关于File.Delete之后,File.Exists返回true的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!