16

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

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

ありがとう、
ロバート

4

4 に答える 4

6

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

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

于 2009-09-11T07:44:15.780 に答える
5

これは、次の手順で、ファイルの周りの 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);
    }
    
于 2012-07-22T00:04:30.033 に答える
4

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

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

私にとって、私が説明するソリューションは非常にシンプルで維持しやすいので、試してプロファイリングします。それに基づいてパフォーマンスの問題が発生することはないと思います。私がこれを行うのは、人々がマルチスレッド ゲームをプレイしていて、CPU 全体を使用していて、私のパーサーが競合するパーサーよりも要求が厳しいと文句を言う人がいないときです。

于 2009-09-11T07:43:26.933 に答える
2

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

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

これは、読み取りが書き込みに追いついたときに、書き込みバッファーがフラッシュされる間、読み取りを実行しているスレッドが一時停止する可能性があるという点で役立ちます。このプロパティがあなたの目的に何らかの形で役立つかどうかを確認するために、小さなテストを作成することは確かに価値があります。

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

于 2009-09-11T08:12:29.313 に答える