System.IO.IOException:进程无法访问该文件,因为它正由另一个进程使用

时间:2013-08-02 16:15:05

标签: c# filestream streamreader filesystemwatcher ioexception

我正在使用FileSystemWatcher来监控日志文件的更改。

日志文件由第三方应用程序写入。

触发更改后,我尝试使用以下方法读取文件:

using (FileStream fs = new FileStream(e.FullPath, FileMode.Open, 
    FileAccess.Read, FileShare.ReadWrite))
{
    StreamReader sr = new StreamReader(fs);
    string s = sr.ReadLine();
}

有时它会在using行失败。

其他时候它在sr.ReadLine()失败,我认为这是因为第三方系统当前正在访问该文件。

我认为通过设置FileAccess.Read我应该能够始终读取文件吗?

如何确保这不会导致异常,或者我是否需要循环才能成功阅读?

1 个答案:

答案 0 :(得分:3)

简短回答:在阅读之前尝试Thread.Sleep(100),然后尽可能快地阅读。

  

我认为通过设置FileAccess.Read我应该能够始终读取文件吗?

通过设置FileAccess.Read,您只需要说明您需要从文件中读取。通过设置FileShare.ReadWrite,您说您在阅读时对第三方阅读和写入文件感到满意。 exception表示第三方在写作时对您的阅读感到不舒服。您的第一个赌注是检查您是否可以配置第三方进程以允许其他进程在写入时读取,但请注意从正在写入的文件中读取可能会很麻烦。

  

如何确保这不会导致异常,或者我是否需要循环才能成功阅读?

只要第三方需要独占锁定,no way to guarantee您就不会获得异常,但您可以采取措施降低冲突风险,主要是:

  • 在他们不写的时候阅读
  • 快速阅读

在他们不写的时候阅读

现在,您正在监控文件并在第三方写入后立即阅读。当你尝试阅读时,他们仍然在写作,所以你应该稍等一下才能完成。我会在阅读前100毫秒尝试Thread.Sleep,但这取决于第三方流程的性质;也就是说,如果它每小时刷新一次,那么你可以等待更多,但如果它每秒写一次,你就等等。

快速阅读

有关如何快速阅读的提示,请参阅this question。另外请记住,您现在正在重复阅读完整的文件。如果它是一个大的附加文件,您可以选择缓存您已阅读的部分,并Seek下次读取时的最后一个已知位置。这样你就可以跳过之前读过的内容。