C#回滚Streamreader 1个字符
对于我正在使用streamreader的C#项目,我需要返回1个字符(基本上类似于撤消),并且我需要更改它,以便在获得下一个字符时,它与回滚时的字符相同 比如说 你好 是的 H E L L O [空白] T H EC#回滚Streamreader 1个字符,c#,project,streamreader,C#,Project,Streamreader,对于我正在使用streamreader的C#项目,我需要返回1个字符(基本上类似于撤消),并且我需要更改它,以便在获得下一个字符时,它与回滚时的字符相同 比如说 你好 是的 H E L L O [空白] T H E R从位置减去一: var bytes = Encoding.ASCII.GetBytes("String"); Stream stream = new MemoryStream(bytes); Console.WriteLine((char)stream.ReadByte()); /
R从位置减去一:
var bytes = Encoding.ASCII.GetBytes("String");
Stream stream = new MemoryStream(bytes);
Console.WriteLine((char)stream.ReadByte()); //S
Console.WriteLine((char)stream.ReadByte()); //t
stream.Position -= 1;
Console.WriteLine((char)stream.ReadByte()); //t
Console.WriteLine((char)stream.ReadByte()); //r
Console.WriteLine((char)stream.ReadByte()); //i
Console.WriteLine((char)stream.ReadByte()); //n
Console.WriteLine((char)stream.ReadByte()); //g
当您不知道是否需要该值时,请使用-而不是
Read()
,这样您就可以在不推进流的情况下检查该值。另一种方法(我在我的一些代码中使用)是将读取器(或者在我的例子中是一个流
)封装在一个类中,该类有一个内部缓冲区,可以让您将值推回。始终首先使用缓冲区,这样就可以轻松地将值(甚至:调整后的值)推回到流中,而不必倒带它(这对许多流都不起作用)。一个干净的解决方案是从StreamReader派生一个类并重写Read()函数
对于您的需求,一个简单的private int lastChar
就足以实现Pushback()方法。一个更通用的解决方案是使用堆栈
来允许无限制的回推
//untested, incomplete
class MyReader : StreamReader
{
public MyReader(Stream strm)
: base(strm)
{
}
private int lastChar = -1;
public override int Read()
{
int ch;
if (lastChar >= 0)
{
ch = lastChar;
lastChar = -1;
}
else
{
ch = base.Read(); // could be -1
}
return ch;
}
public void PushBack(char ch) // char, don't allow Pushback(-1)
{
if (lastChar >= 0)
throw new InvalidOperation("PushBack of more than 1 char");
lastChar = ch;
}
}
我认为这是不可能的,因为当你阅读一条流时,它返回并前进,而这已经过去了。对于文件和内存流,这可能是可行的,但请考虑网络流。你读了数据,它进入,它被处理,永远消失,它没有“存储”在某个地方。但是,如果您特别希望将其用于内存流,您可能会使用不安全的代码并执行一些指针算法,我认为它应该可以工作..对于StreamReader,请访问其BaseStream属性并设置其位置。并非所有流都具有CanSeek()==true。请记住,Position属性仅受某些流实现的支持,例如,NetworkStream不支持它。使用流的CanSeek属性确定是否可能。-1原因有三:a:byte!=字符,b:问题是流阅读器,c:不是所有的流都是seekable@Ryan-此外,重新“访问其基本流”-如果这样做,还需要担心读卡器的缓冲区-并且,并非所有流都是可搜索的(如果可能,最好避免搜索)