我使用TextReader
从文本文件中读取数据。
TextReader reader = new StreamReader(stream);
string line;
while ((line = reader.ReadLine()) != null)
{
//.......
}
有时我需要从读取器中窥视下一行(或几行)。
那我该怎么做呢?
编辑:已更新以允许任意数量的预览:
public class PeekingStreamReader : StreamReader
{
private Queue<string> _peeks;
public PeekingStreamReader(Stream stream) : base(stream)
{
_peeks = new Queue<string>();
}
public override string ReadLine()
{
if (_peeks.Count > 0)
{
var nextLine = _peeks.Dequeue();
return nextLine;
}
return base.ReadLine();
}
public string PeekReadLine()
{
var nextLine = ReadLine();
_peeks.Enqueue(nextLine);
return nextLine;
}
}
你需要自己完成这个任务,但并不难:
public class PeekTextReader {
string lastLine;
private readonly TextReader reader;
public PeekTextReader(TextReader reader) {
this.reader = reader;
}
public string Peek() {
return lastLine ?? (lastLine = reader.ReadLine());
}
public string ReadLine() {
string res;
if (lastLine != null) {
res = lastLine;
lastLine = null;
} else {
res = reader.ReadLine();
}
return res;
}
}
ReadLine
操作。ReadLine
的调用者来说,并不会像 Peek
一样知道:对他们而言,调用 Peek
并不像读取一样,因为下一次调用 ReadLine
将把选定的行返回给您。换句话说,被查看的行并没有被消耗。 - Sergey KalinichenkoPeek
会发生什么?这些细节是强大的实用类中的致命问题。 - SAJ14SAJIDisposable
来关闭内部读取器。 - Alexei Levenkov在文本阅读器中,没有可靠的方法可以向后移动阅读位置。您可以尝试查找底层流,但这可能不可能(如果流不支持查找),或者如果阅读器内部发生任何类型的缓存,则可能无法获得所需的结果。
最可靠的方法是记住最后一行,您可以考虑创建自定义类,将其扩展为具有PeekString功能的阅读器...但是,如果您需要使用其他阅读器方法重新读取该字符串,则可能难以正确实现。
while(not end of line) str+=reader.Peek()
这样的东西。这有关系吗? - Alan Coromano你可以使用“ReadAllLines”函数读取文件中的所有行,然后对它们进行简单的操作。但是请注意,如果文件过大,这将会占用过多的内存。
Queue<string>
来允许任意数量的peek。 - armen.shimoonStreamReader
类的情况我会给出+1分,该类是一个具体类,而不是抽象类TextReader
(我刚刚检查过,因为我知道有些事情让我感到困扰)。 - SAJ14SAJEndOfStream
存在问题,因为它需要检查EndOfStream
属性和没有预读的行。不幸的是,您无法覆盖基本属性,但是您可以很容易地添加自己的函数。 - Jack Aidley