首页 > 解决方案 > 在同一个 Stream 上创建多个 StreamReader 的奇怪行为

问题描述

我正在使用有限状态机来读取一个超大文件。它不是多线程的,所以不会有线程安全的问题。

它包含3种内容:

我发现这个问题可能有用,但它失败了。类似的python 问题也没有用,因为它不会抛出任何错误。我必须以正确的编码阅读内容,否则行为将变得未知。

目前,我正在使用StreamReader,但是一旦 StreamReader 初始化,就无法更改CurrentEncoding属性。

所以我也尝试在同一个Stream上重新创建 StreamReader :

reader = new StreamReader(stream, encoding65001); //UTF-8
DoSomething(reader);
reader = new StreamReader(stream, encoding1252); //ANSI
DoSomething(reader);
reader = new StreamReader(stream, encoding936); //ANSI

//...

但它开始从一个未知的位置读取奇怪的内容。我还没有找出这种奇怪行为的可能原因。

我是否在创建多个StreamReader时犯了错误,或者它被设计为不在同一个流上创建多个

如果是这样设计的,是否有读取此类文件的解决方案?

感谢您花时间阅读。

编辑: 我在 .NET Core 3.1 上运行了以下代码:

Stream stream = File.OpenRead(testFilePath);
Console.WriteLine(stream.Position);
Console.WriteLine(stream.ReadByte());
Console.WriteLine(stream.Position + "\r\n");

StreamReader reader = new StreamReader(stream, Encoding.UTF8);
Console.WriteLine(reader.Read());
Console.WriteLine(stream.Position + "\r\n");

reader = new StreamReader(stream, CodePagesEncodingProvider.Instance.GetEncoding(1252));
Console.WriteLine(reader.Read());
Console.WriteLine(stream.Position);

使用以下示例文本:

abcdefg

和输出:

0
97
1

98
7

-1
7

这很奇怪也很有趣。

标签: c#encodingstreamreader

解决方案


流阅读器将从他们正在阅读的底层流中缓冲内容,这就是导致您出现问题的原因。仅仅因为您从阅读器中读取了一个字符,并不意味着它只会从底层流中读取一个字符。它会用字节填充一段时间缓冲区,然后从缓冲区中产生一个字符。

如果您想从流中读取值并将不同的字节部分解释为不同的编码(为了记录,如果可能的话,您应该避免将自己置于数据中混合编码的位置),您将不得不拉自己从流中取出字节,然后使用适当的编码转换字节,这样您就可以确保只提取您想要的字节的确切部分,而不是更多。


推荐阅读