15

変更を監視し、独自の変更を追加したいデータを含むファイルがあります。「Tail -f foo.txt」のように考えてください。

このスレッドに基づいて、ファイルストリームを作成し、それをライターとリーダーの両方に渡す必要があるようです。ただし、リーダーが元のファイルの最後に到達すると、自分で書いた更新が表示されません。

奇妙な状況のように思えることはわかっています...それができるかどうかを確認するための実験です.

私が試した例は次のとおりです。


foo.txt:
a
b
c
d
e
f


        string test = "foo.txt";
        System.IO.FileStream fs = new System.IO.FileStream(test, System.IO.FileMode.OpenOrCreate, System.IO.FileAccess.ReadWrite);

        var sw = new System.IO.StreamWriter(fs);
        var sr = new System.IO.StreamReader(fs);

        var res = sr.ReadLine();
        res = sr.ReadLine();
        sw.WriteLine("g");
        sw.Flush();
        res = sr.ReadLine();
        res = sr.ReadLine();
        sw.WriteLine("h");
        sw.Flush();
        sw.WriteLine("i");
        sw.Flush();
        sw.WriteLine("j");
        sw.Flush();
        sw.WriteLine("k");
        sw.Flush();
        res = sr.ReadLine();
        res = sr.ReadLine();
        res = sr.ReadLine();
        res = sr.ReadLine();
        res = sr.ReadLine();
        res = sr.ReadLine();

"f" を過ぎると、リーダーは null を返します。

4

4 に答える 4

24

わかりました、2回の編集後...

これはうまくいくはずです。初めて試したとき、oStream に FileMode.Append を設定するのを忘れていたと思います。

string test = "foo.txt";

var oStream = new FileStream(test, FileMode.Append, FileAccess.Write, FileShare.Read); 
var iStream = new FileStream(test, FileMode.Open, FileAccess.Read, FileShare.ReadWrite); 

var sw = new System.IO.StreamWriter(oStream);
var sr = new System.IO.StreamReader(iStream); 
var res = sr.ReadLine(); 
res = sr.ReadLine();
sw.WriteLine("g"); 
sw.Flush(); 
res = sr.ReadLine();
res = sr.ReadLine();
sw.WriteLine("h"); sw.Flush();
sw.WriteLine("i"); sw.Flush(); 
sw.WriteLine("j"); sw.Flush(); 
sw.WriteLine("k"); sw.Flush(); 
res = sr.ReadLine(); 
res = sr.ReadLine(); 
res = sr.ReadLine();
res = sr.ReadLine();
res = sr.ReadLine();
res = sr.ReadLine();
于 2010-09-28T22:37:45.897 に答える
10

@mikerobi は正しいです。ストリームに書き込むと、ファイル ポインタが変更され、ストリームの最後に移動されます。あなたが期待していないのは、StreamReader が独自のバッファを持っているということです。ファイルから 1024 バイトを読み取り、そのバッファから結果を取得します。バッファがなくなるまで、FileStream から再度読み取る必要があります。ファイル ポインタがファイルの末尾にあるため、何も見つかりません。

これを機能させるには、それぞれに独自のファイル ポインターを持つ FileStream を分離する必要があります。

于 2010-09-28T23:10:54.397 に答える
3

文字を書くたびにストリームの位置を進めていると思うので、次の読み取りでは、今書いた文字の後に読み取ろうとします。これは、ストリーム リーダーとストリーム ライターが同じ FileStream を使用しているために発生します。別のファイル ストリームを使用するか、書き込みのたびにストリーム内で -1 文字をシークします。

于 2010-09-28T22:35:19.130 に答える
2

読み取りと書き込みに同じストリームを使用することを含む、この問題の解決策に満足する可能性はほとんどありません。.を使用してファイルの末尾を読み取ろうとしている場合は特にそうですStreamReader

2 つの異なるファイル ストリームが必要です。書き込みストリームは、必要にStreamWriter応じて にすることができます。読み取りストリームはバイナリ ストリーム (File.OpenReadまたはで作成FileStream.Create) で、ファイルから生のバイトを読み取り、テキストに変換する必要があります。この質問に対する私の答えは、それがどのように行われるかの基本を示しています。

于 2010-09-28T23:09:20.650 に答える