即使关闭调用应用程序,删除功能也会删除

时间:2012-08-01 14:52:23

标签: c# file delete-file

我遇到了一个奇怪的问题(可能是我缺乏知识),我提出了令人讨厌的代码:

try
{
    f.Delete();
    fTemp.MoveTo(f.FullName);
    Console.WriteLine("INFO: Old file deleted new file moved in > {0}", f.FullName);
}
catch (IOException ex)
{
    Console.WriteLine("ERROR: Output file has IO exception > {0}", f.FullName);
    Environment.ExitCode = 1;
}

f和fTemp是FileInfo对象。因此,如果我使用代码执行此操作,其中f是在媒体播放器中播放的视频文件,则会抛出异常。这工作正常,如预期的那样。现在,当我关闭媒体播放器时,它会删除文件!?即使我的申请被长期关闭。即使我关闭Visual Studio,当我关闭媒体播放器时它仍会删除该文件。好像某个回调正在某处设置,以确保文件在某个时刻被删除。这种不受欢迎的行为。但我无法弄清楚到底出了什么问题......

现在的结果:

if (!IsFileLocked(f))
{
    try
    {
        f.Delete();
        fTemp.MoveTo(f.FullName);
        Console.WriteLine("INFO: Old file deleted new file moved in > {0}", f.FullName);
    }
    catch (IOException ex)
    {
        Console.WriteLine("ERROR: Output file has IO exception > {0}", f.FullName);
        Environment.ExitCode = 1;

    }

    catch (UnauthorizedAccessException ex)
    {
        Environment.ExitCode = 2;
        Console.WriteLine("ERROR: Output file is locked > {0}", f.FullName);

    }
}
else
{
    Environment.ExitCode = 3;
    Console.WriteLine("ERROR: Couldn't delete file was locked");

}

我知道我仍然可以在删除和MoveTo之间做得更好,但我现在将采取我的更改,猎枪编码......

3 个答案:

答案 0 :(得分:3)

您收到IOException,因为无法立即删除或写入该文件。但是,当您调用Delete()时,似乎会调用该文件进行删除。

虽然媒体播放器会在文件打开时阻止文件被删除,但文件在关闭时仍会标记为删除,无论您的程序是否正在运行。因此,当媒体播放器关闭时,文件将被删除。

您可以使用以下代码检查文件是否正在使用,该代码取自here。以DeleteCopy为条件使其不被锁定,你应该做得好。

try
{
    if(!IsFileLocked(f))
    {
        f.Delete();
        fTemp.MoveTo(f.FullName);
        Console.WriteLine("INFO: Old file deleted new file moved in > {0}", f.FullName);
    }
}

protected virtual bool IsFileLocked(FileInfo file)
{
    FileStream stream = null;

    try
    {
    stream = file.Open(FileMode.Open, FileAccess.ReadWrite, FileShare.None);
    }
    catch (IOException)
    {
    //the file is unavailable because it is:
    //still being written to
    //or being processed by another thread
    //or does not exist (has already been processed)
    return true;
    }
    finally
    {
    if (stream != null)
        stream.Close();
    }

    //file is not locked
    return false;
}

答案 1 :(得分:1)

来自Windows SDK:

DeleteFile函数在关闭时标记要删除的文件。因此,在关闭文件的最后一个句柄之前不会发生文件删除。随后调用CreateFile以打开文件失败,并显示ERROR_ACCESS_DENIED。

答案 2 :(得分:0)

据我了解,您希望程序等到文件被删除后删除它并移动另一个文件。

要执行此操作,您可以检查文件上是否打开了句柄,但这需要非托管代码。另一种方法是使用这个问题的答案中的方法:Is there a way to check if a file is in use?

protected virtual bool IsFileLocked(FileInfo file) 
{ 
    FileStream stream = null; 

    try 
    { 
        stream = file.Open(FileMode.Open, FileAccess.ReadWrite, FileShare.None); 
    } 
    catch (IOException) 
    { 
        //the file is unavailable because it is: 
        //still being written to 
        //or being processed by another thread 
        //or does not exist (has already been processed) 
        return true; 
    } 
    finally 
    { 
        if (stream != null) 
            stream.Close(); 
    } 

    //file is not locked 
    return false; 
} 

开始删除文件之前

A)循环直到可以删除文件

while(IsFileLocked(f)) { Thread.Sleep(100); }

或B)取消

if (IsFileLocked(f)) { return; }

如果您选择A或B取决于您的要求。