我有一个应用程序,我有时需要从正在写入的文件中读取并因此被锁定。正如我从其他questions理解的那样,我应该捕获IOException并重试直到我能够阅读。
但我的问题是我如何确定该文件被锁定并且它不是另一个IOExcetpion发生的。
答案 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));