8

当我使用文本阅读器时,检测我实际上处于数据末尾的最佳方法是什么?执行此操作的通常方法如下所示

    while(reader.Peek() != -1)
    {
       ///do stuff
    }

但是这里的 msdn 文档说明了以下内容

表示要读取的下一个字符的整数,如果没有更多字符可用或读取器不支持查找,则为 -1。

所以我的问题是你如何判断你是否真的处于读者数据的末尾,或者读者/基础流根本不支持搜索,因为这里的返回值似乎是模棱两可的?如果例如我有以下

    public void Parse(TextReader reader)
    {
         while(reader.Peek() != -1) //am I really at the end
         {
            //do stuff
         }
    }

    Parse(new StreamReader(new NetworkStream(....)));

因为 networkstream 不支持搜索。

还是我错过了什么?

编辑:

澄清一下,我可以使用更具体的 StreamReader 类轻松实现这一点,因为我可以检查 EoS。然而,为了让事情更笼统,我想使用 TextReader,所以我不仅仅局限于 StreamReader。但是 Peek 的语义似乎有点奇怪,如果不支持搜索,为什么它不直接抛出,为此为什么没有 TextReader 的 EoF 属性?

4

4 回答 4

5

除非您正在使用 Peek() 寻找特定值,否则为什么不使用 .Read()

例如

string line;
System.IO.StreamReader file = new System.IO.StreamReader(strfn);
while((line = file.ReadLine()) != null)
{
  this.richTextBox1.AppendText(line+"\n");//you can replace this line to fit your UseCase
}

如果你想要一个更简洁的例子来说明如何做到这一点,你可以做一些我在它下面发布的可读的事情,你可以插入你自己的文本文件值并调试它以查看它是否可以工作。读写

string tempFile = Path.GetTempFileName();
using(var sr = new StreamReader("file.txt"))
{
  using(var sw = new StreamWriter(tempFile))
  {
    string line;
    while((line = sr.ReadLine()) != null)
    {
         if(line != "BlaBlaBla")
             sw.WriteLine(line);
    }
  }
}

这是您可以尝试的另一种选择

从 aStream中,如果你Read(buffer, offset, count)得到一个非阳性结果,如果你Peek()得到一个否定结果。

使用 a BinaryReader文档建议PeekChar()应该返回负数:

返回值

类型:System.Int32 下一个可用字符,如果没有更多可用字符或流不支持查找,则为 -1。

你确定这不是一个损坏的流吗?即剩余的数据不能char从给定的编码中形成一个完整的?

于 2012-11-30T18:12:30.423 回答
4

它应该是 reader.Read() == -1 不再存在,否则字符存在。

于 2012-11-30T18:06:42.287 回答
4

这实际上取决于您在解析中所做的事情。

我通常只是Read,看看读了多少。我建议不要一次读一个字符:

char[] buffer = new char[1024 * 16];
int charsRead;
while ((charsRead = read.Read(buffer, 0, buffer.Length)) > 0)
{
    // Process buffer, only as far as charsRead
}
于 2012-12-01T09:02:05.900 回答
0

如果您只需要读取和处理所有数据直到流结束,那么您应该Read直接使用,如果没有更多字符可用,则返回 -1。

int nextByte;
while ((nextByte = reader.ReadByte()) != -1)
    // Process nextByte here.

编辑:专门检查读者是否支持搜索的另一种方法是检查底层流:

bool canSeek = reader.BaseStream.CanSeek;

如果返回truePeek则只应在到达流末尾时返回 -1。

于 2012-11-30T18:11:46.487 回答