我正在为 C# 中的解析器制作一个自定义输入读取器,并且我试图从流读取器中查看第 n 个字符而不移动流位置,这样当多次调用该函数时我会得到相同的输出(就像内置的窥视功能)。
我当前可以获得第 n 个元素,如下面的代码所示,但是在执行此操作时,我移动了流位置,因此每次调用我都会得到不同的字符。
private StreamReader _reader;
private int _peekChar = -1;
public InputReader(Stream inputStream)
{
_reader = new StreamReader(inputStream);
}
// Returns the next character in the input stream without consuming it
public char Peek()
{
// Checks if character already peeked
if (_peekChar == -1)
_peekChar = _reader.Peek();
return (char)_peekChar;
}
// Returns the n th next character in the input stream without consuming it
public char Peek(int n)
{
if (n <= 0)
throw new ArgumentException("n must be a positive integer.");
char[] buffer = new char[n];
int bytesRead = _reader.Read(buffer, 0, n);
if (bytesRead < n)
throw new EndOfStreamException("Not enough characters in the stream to peek.");
return buffer[n - 1];
}
假设我使用
"<HTML> <p> test <p/> <HTML/>"
在流上调用 Peek(1) 3 次,我期望 3 个 <
的输出,但是我得到 <
H
T
当你
_reader.Read(buffer, 0, n);
然后流的位置增加。
读取后需要将流的位置向后移动(如果流支持)
_reader.Seek(-bytesRead, SeekOrigin.End);
在这种情况下,我会编写一个“PeekableStream”,它维护一个可以查看的缓冲区。如果可用,它将从缓冲区中提取字符,然后在缓冲区耗尽时从原始流中提取字符。缓冲区根据传递给 Peek 方法的“n”进行扩展和填充。