File.Delete之后,File.Exists返回true [英] File.Exists returns true after File.Delete

查看:203
本文介绍了File.Delete之后,File.Exists返回true的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我可以通过以下方法删除具有提供的路径的文件

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

System.IO.IOException):无法删除文件:"C:\ Windows \ TEMP \ [文件名]".

System.IO.IOException): Failed to delete file: 'C:\Windows\TEMP\[FILE NAME]'.

我还确认执行完成后,该文件在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):

DeleteFile函数将文件标记为关闭时要删除.所以, 直到文件的最后一个句柄是 关闭

The DeleteFile function marks a file for deletion on close. Therefore, the file deletion does not occur until the last handle to the file is closed

通常,没有删除文件的打开句柄.或者,如果有打开的句柄-它们通常没有删除"共享(此共享允许另一个进程将文件标记为删除),所以当您尝试删除此类文件时-它要么被删除(没有打开的句柄),要么拒绝访问或引发类似异常(某些句柄,但没有删除共享).

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的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆