3

Random.txtから5文字ごとに読み取るこの小さなプログラムを作成しました。random.txtには、ABCDEFGHIJKLMNOPRSTという1行のテキストがあります。期待どおりの結果が得られました。

  • Aの位置は0です
  • Fの位置は5です
  • Kの位置は10です
  • Pの位置は15です

コードは次のとおりです。

static void Main(string[] args)
{
    StreamReader fp;
    int n;
    fp = new StreamReader("d:\\RANDOM.txt");
    long previousBSposition = fp.BaseStream.Position;
    //In this point BaseStream.Position is 0, as expected
    n = 0;

    while (!fp.EndOfStream)
    {
        //After !fp.EndOfStream were executed, BaseStream.Position is changed to 19,
        //so I have to reset it to a previous position :S
        fp.BaseStream.Seek(previousBSposition, SeekOrigin.Begin);
        Console.WriteLine("Position of " + Convert.ToChar(fp.Read()) + " is " + fp.BaseStream.Position);
        n = n + 5;
        fp.DiscardBufferedData();
        fp.BaseStream.Seek(n, SeekOrigin.Begin);
        previousBSposition = fp.BaseStream.Position;
    }
}

私の質問は、なぜ行while (!fp.EndOfStream) BaseStream.Positionが19に変更されたのか、たとえばの終わりですBaseStreamBaseStream.Position私がチェックを呼び出すとき、それは明らかに同じままであると私は予想しました、明らかに間違っていますEndOfStreamか?

ありがとう。

4

3 に答える 3

4

aStreamが最後にあるかどうかを確認する唯一の確実な方法は、実際にそこから何かを読み取り、戻り値が0であるかどうかを確認するStreamReaderことです。呼び出しDiscardBufferedDataます。)

したがって、EndOfStreamベースストリームから少なくとも1バイトを読み取る必要があります。また、バイトごとの読み取りは非効率的であるため、より多くの読み取りが行われます。これが、toの呼び出しが位置を最後に変更する理由EndOfStreamです(大きなファイルの場合、ファイルの終わりにはなりません)。

実際に使用する必要はないようですStreamReaderので、直接Stream(または具体的に)使用する必要があります。FileStream

using (Stream fp = new FileStream(@"d:\RANDOM.txt", FileMode.Open))
{
    int n = 0;

    while (true)
    {
        int read = fp.ReadByte();
        if (read == -1)
            break;

        char c = (char)read;
        Console.WriteLine("Position of {0}  is {1}.", c, fp.Position);
        n += 5;
        fp.Position = n;
    }
}

(この状況でファイルの終わりを超えて位置を設定するとどうなるかわかりません。そのためのチェックを追加する必要があるかもしれません。)

于 2011-09-29T14:05:56.450 に答える
2

基本ストリームのプロパティは、StreamReader のカーソルの実際の位置ではなく、bufferPosition内の最後に読み取られたバイトの位置を参照します。

于 2011-09-29T12:49:13.203 に答える
1

あなたは正しいです、そして私もあなたの問題を再現することができます、とにかく(MSDN:ファイルからテキストを読む)によると、StreamReaderでテキストファイルを読む適切な方法はあなたのものではなく次のとおりです(これも常にストリームを閉じて破棄しますusingブロックを使用して):

try
{
    // Create an instance of StreamReader to read from a file.
    // The using statement also closes the StreamReader.
    using (StreamReader sr = new StreamReader("TestFile.txt"))
    {
        String line;
        // Read and display lines from the file until the end of
        // the file is reached.
        while ((line = sr.ReadLine()) != null)
        {
            Console.WriteLine(line);
        }
    }
}
catch (Exception e)
{
    // Let the user know what went wrong.
    Console.WriteLine("The file could not be read:");
    Console.WriteLine(e.Message);
}
于 2011-09-29T12:11:20.477 に答える