Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/260.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C#回滚Streamreader 1个字符_C#_Project_Streamreader - Fatal编程技术网

C#回滚Streamreader 1个字符

C#回滚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()); /

对于我正在使用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()); //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-此外,重新“访问其基本流”-如果这样做,还需要担心读卡器的缓冲区-并且,并非所有流都是可搜索的(如果可能,最好避免搜索)