当我使用文本阅读器时,检测到我实际上在数据末尾的最佳方法是什么?通常的方法是喜欢以下,
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属性?
答案 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。