如何最好等待文件锁释放

时间:2009-03-27 15:32:20

标签: c# .net ioexception filelock

我有一个应用程序,我有时需要从正在写入的文件中读取并因此被锁定。正如我从其他questions理解的那样,我应该捕获IOException并重试直到我能够阅读。

但我的问题是我如何确定该文件被锁定并且它不是另一个IOExcetpion发生的。

6 个答案:

答案 0 :(得分:5)

当你打开一个文件以便在.NET中阅读时,它会在某个时候尝试使用CreateFile API函数创建一个文件句柄,该函数设置error code可以用来查看它失败的原因:

const int ERROR_SHARING_VIOLATION = 32;
try
{
    using (var stream = new FileStream("test.dat", FileMode.Open, FileAccess.Read, FileShare.Read))
    {
    }
}
catch (IOException ex)
{
    if (Marshal.GetLastWin32Error() == ERROR_SHARING_VIOLATION)
    {
        Console.WriteLine("The process cannot access the file because it is being used by another process.");
    }
}

答案 1 :(得分:4)

有关google groups的有用讨论,你真的应该阅读。其中一个选择是接近darin的;但是,为了保证你得到正确的win32错误,你真的应该自己调用win32 OpenFile()API(否则,你真的不知道你正在检索哪个错误)。

另一种方法是解析错误消息:如果您的应用程序在另一种语言版本上运行,则会失败。

第三个选项是使用反射在异常类中进行破解以捕获实际的HRESULT。

没有其他选择真正具有吸引力:IOException层次结构将受益于更多的子类恕我直言。

答案 2 :(得分:0)

要阅读数据,您可以这样做:

  

使用(FileStream fs = new   FileStream(fileName,FileMode.Open,   FileAccess.Read,FileShare.ReadWrite |   FileShare.Delete)){....}

并保存到文件中:

  

使用(FileStream fs = new   FileStream(fileName,FileMode.Append,   FileAccess.Write,FileShare.Read |   FileShare.Delete)){...}

构造函数末尾的标志描述了其他进程可以对文件执行的操作。当然,如果您同时控制写入和读取,那很好......

答案 3 :(得分:0)

您可以与IOException类型进行比较,以检查它是否不是其他

if (ex is FileNotFoundException)

您可能希望在System.IO上查找帮助。该类中的许多例外都是从IOException继承的。在检查是否是另一种类型的异常之外,您可能需要查看描述的消息,或者您可能会考虑对shell32.dll进行Win32 API调用。可能有一个函数来检查文件是否被锁定。

另外,如果你绝对需要等待,你可以使用循环,但如果你想在等待使用异步线程时做其他动作。

答案 4 :(得分:0)

您可以打开它(如bezieur所述)然后尝试锁定部分(或整个文件): http://www.java2s.com/Code/VB/File-Directory/Lockandunlockafile.htm

答案 5 :(得分:0)

您的意思是说您正在阅读和写入文件吗?或者外部应用程序正在写入它。

如果您正在进行读写,那么我假设您在不同的线程上进行,在这种情况下,请查看ReaderWriteLock类,它将为您执行此管理,并允许您提供超时。

http://msdn.microsoft.com/en-us/library/system.threading.readerwriterlock.aspx

否则,您只需以只读模式打开文件即可。那你就不应该有任何问题:

fileStream = new FileStream(fileName, FileMode.Open, FileAccess.Read));