TextReader.Peek行为和检测流/阅读器的结束

时间:2012-11-30 18:04:07

标签: c# .net textreader

当我使用文本阅读器时,检测到我实际上在数据末尾的最佳方法是什么?通常的方法是喜欢以下

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

然而,msdn文档here声明了以下内容

  

表示要读取的下一个字符的整数,如果没有更多字符可用或读者不支持搜索,则返回-1。

所以我的问题是你怎么知道你是否真的在读者数据的末尾,或者读者/底层流只是不支持寻求,因为这里的返回值似乎含糊不清?如果我有以下

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

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

因为网络流不支持寻求。

或者我错过了什么?

修改

为了澄清一点,我可以使用更具体的StreamReader类轻松实现这一点,因为我可以检查EoS。但是为了保持一般性,我想使用TextReader,所以我不仅仅与StreamReader绑定。然而,Peek的语义似乎有点奇怪,为什么它不仅仅是在寻求不支持的情况下抛出,为此为什么没有TextReader的EoF属性?

4 个答案:

答案 0 :(得分:4)

除非您使用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);
    }
  }
}

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

Stream开始,如果您Read(buffer, offset, count),您将获得非阳性结果,如果您Peek(),您将获得否定结果。

使用BinaryReader时,the documentation表示PeekChar()应返回否定值:

  

返回值

     

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

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

答案 1 :(得分: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
}

答案 2 :(得分:3)

它应该是reader.Read()== -1不再存在或其他字符存在。

答案 3 :(得分:0)

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

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

编辑:另一种检查读者是否支持搜索的方法是检查基础流:

bool canSeek = reader.BaseStream.CanSeek;

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