質問

C#/。NET(Windows)には、「成長中」を読み取る方法があります。ファイルストリームを使用してファイル?ファイルストリームが開かれるとき、ファイルの長さは非常に短くなりますが、ファイルは別のスレッドによって書き込まれます。ファイルストリームが「追いつく」場合/いつ他のスレッドに(つまり、 Read()が0バイトの読み取りを返した場合)、一時停止してファイルが少しバッファリングできるようにしてから、読み取りを続行します。

FilesystemWatcher を実際に使用し、新しいファイルストリームを作成し続けたくありません(ログファイルに推奨されたように)。これはログファイルではないためです(エンコードされているビデオファイルオンザフライ)とパフォーマンスが問題です。

ありがとう、
ロバート

役に立ちましたか?

解決

これを行うことはできますが、 Stream.Seek を使用し、スレッド間の適切な同期を使用して、ファイルの読み取りおよび書き込み位置を注意深く追跡する必要があります。通常、 EventWaitHandle またはそのサブクラスを使用してデータの同期を行います。また、 FileStream オブジェクト自体へのアクセスの同期を検討する必要があります(おそらく lock ステートメント)。

更新: この質問に答える際に似たようなものを実装しました。ファイルはバックグラウンドでダウンロードされ、同時にアップロードされていました。メモリバッファーを使用し、動作するコードがある gist を投稿しました。 (それはGPLですが、それはあなたにとって重要ではないかもしれません-いずれにしても、あなたはあなた自身のことをするために原則を使うことができます。)

他のヒント

これを解決する方法は、 DirectoryWatcher / FilesystemWatcherクラスを使用することです。そして、それがファイルでトリガーされたら、FileStreamを開いて最後まで読み取ります。読み終わったら、リーダーの位置を保存します。次回は DirectoryWatcher / FilesystemWatcherは、ストリームを開き、前回の位置に位置を設定します。

FileStream.lengthの呼び出しは実際には非常に遅く、ソリューションでパフォーマンスの問題は発生していません(10 MBから50 ishの範囲の「ログ」を読んでいた)。

私が説明するソリューションは非常にシンプルでメンテナンスが簡単です。試してプロファイルを作成します。これに基づいてパフォーマンスの問題が発生するとは思わない。これは、pplがマルチスレッドゲームをプレイしてCPU全体を使用しているときに、競合するパーサーよりも私のパーサーの方が要求していると文句を言う人はいません。

これは、ファイル周辺のStreamReaderで次の手順で機能しました:

  1. ファイルに書き込むプログラムで、次のように読み取り共有で開きます:

    var out = new StreamWriter(File.Open("logFile.txt",  FileMode.OpenOrCreate, FileAccess.Write, FileShare.Read));
    
  2. ファイルを読み取るプログラムで、次のように読み書き共有でファイルを開きます。

    using (FileStream fileStream = File.Open("logFile.txt", FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
    using ( var file = new StreamReader(fileStream))
    
  3. 入力ストリームにアクセスする前に、最後に到達したかどうかを確認し、到達している場合はしばらく待ちます。

    while (file.EndOfStream)
    {
        Thread.Sleep(5);
    }
    

有用な可能性があるもう1つのことは、FileStreamクラスにReadTimeOutというプロパティがあり、次のように定義されていることです。

ストリームがタイムアウトする前に読み取りを試みる時間を決定する値をミリ秒単位で取得または設定します。 (Streamから継承)

これは、読み取りが書き込みに追いつくと、書き込みバッファーがフラッシュされる間、読み取りを実行しているスレッドが一時停止する場合があるので便利です。このプロパティが何らかの方法であなたの原因に役立つかどうかを確認する小さなテストを書く価値があります。

読み取り操作と書き込み操作は同じオブジェクトで行われていますか?その場合、ファイルに独自の抽象化を記述し、書き込みを実行しているスレッドが読み取りを実行するスレッドに通知するようにクロススレッド通信コードを記述して、読み取りを実行するスレッドが読み取りを停止するタイミングを知ることができますEOFに達したとき。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top