3

我正在使用 aFileSystemWatcher来监视日志文件的更改。

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

一旦触发更改,我将尝试使用以下方式读取文件:

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(),我认为这是因为第 3 方系统当前正在访问该文件。

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

我如何确保这不会导致异常,或者我是否需要循环直到我可以成功读取?

4

1 回答 1

3

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

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

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

我如何确保这不会导致异常,或者我是否需要循环直到我可以成功读取?

只要第 3 方需要排他锁,就无法保证您不会得到异常,但您可以采取一些措施来降低冲突风险,主要是:

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

在他们不写的时候读

现在,您正在监视文件并在第 3 方写入后立即读取。当您尝试阅读时,它们可能仍在写作,因此您应该等待它们完成。我会Thread.Sleep在阅读前尝试 100 毫秒,但这取决于第三方流程的性质;即,如果它每小时刷新一次日志,那么您可以等待更多,但如果它每秒写入一次,您等待的时间会更少。

快速阅读

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

于 2014-05-25T15:26:51.443 回答