3

を使用して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ことで、常にファイルを読み取ることができるはずだと思いましたか?

これが例外を引き起こさないことを確認するにはどうすればよいですか、または正常に読み取れるまでループする必要がありますか?

4

1 に答える 1

3

簡単な答え:Thread.Sleep(100)読む前に試してから、できるだけ速く読んでください。

を設定するFileAccess.Readことで、常にファイルを読み取ることができるはずだと思いましたか?

設定FileAccess.Readすることで、ファイルから読み取る必要があると言っているだけです。設定FileShare.ReadWriteすることにより、ファイルを読んでいる間、サードパーティによるファイルの読み取りと書き込みに慣れていると言えます。これexceptionは、サード パーティが書き込み中にあなたが読むことを快く思わないことを意味します。最初の賭けは、他のプロセスが書き込み中に読み取りできるようにサードパーティのプロセスを構成できるかどうかを確認することですが、書き込み中のファイルからの読み取りは面倒な場合があることに注意してください。

これが例外を引き起こさないことを確認するにはどうすればよいですか、または正常に読み取れるまでループする必要がありますか?

サード パーティが排他的ロックを必要とする限り、例外が発生しないことを保証する方法はありませんが、主に次のような競合のリスクを軽減するための手順があります。

  • 書かないときに読む
  • 速く読む

書かないときに読む

現在、ファイルを監視しており、サードパーティが書き込みを行うとすぐに読み取ります。読み込もうとすると、まだ書き込んでいる可能性があるため、読み終わるまで少し待つ必要があります。読み取る前に 100 ミリ秒を試しThread.Sleepてみますが、サードパーティのプロセスの性質によって異なります。つまり、ログを 1 時間ごとにフラッシュする場合はさらに待つことができますが、1 秒ごとに書き込む場合は待ち時間が短くなります。

速く読む

速く読む方法のヒントについては、この質問を参照してください。また、現在、完全なファイルを繰り返し読んでいることに注意してください。追加ファイルが大きい場合は、既に読み取った部分とSeek次の読み取り時に最後に認識された位置をキャッシュするオプションがあります。このようにして、以前に読んだものをスキップします。

于 2014-05-25T15:26:51.443 に答える