我遇到了一个奇怪的问题(可能是我缺乏知识),我提出了令人讨厌的代码:
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之间做得更好,但我现在将采取我的更改,猎枪编码......
答案 0 :(得分:3)
您收到IOException
,因为无法立即删除或写入该文件。但是,当您调用Delete()
时,似乎会调用该文件进行删除。
虽然媒体播放器会在文件打开时阻止文件被删除,但文件在关闭时仍会标记为删除,无论您的程序是否正在运行。因此,当媒体播放器关闭时,文件将被删除。
您可以使用以下代码检查文件是否正在使用,该代码取自here。以Delete
和Copy
为条件使其不被锁定,你应该做得好。
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取决于您的要求。