在同一 Stream 上创建多个 StreamReader 的奇怪行为
Strange behavior creating multiple StreamReader on the same Stream
我正在使用有限状态机读取超大文件。不是多线程,不会有线程安全问题
包含3种内容:
- 二进制数,表示后面字符串的长度,一个字符计为1
- ANSI,一个字符占用1~2个字节
- UTF-8,一个字符占用1~4个字节
我发现 that might be useful, but it failed. The similiar 都没有用,因为它不会抛出任何错误。我必须使用正确的编码来阅读内容,否则行为将变得未知。
目前,我正在使用 StreamReader, but the CurrentEncoding 属性 无法更改,一旦 StreamReader 被初始化。
所以我也尝试在同一个 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
奇怪又有趣
流 reader 将缓冲它们正在读取的基础流中的内容,这就是导致您出现问题的原因。仅仅因为您从 reader 中读取了一个字符并不意味着它只会从基础流中读取一个字符。它会用字节填充一个 while 缓冲区,然后从缓冲区中给你一个字符。
如果你想从流中读取值并将字节的不同部分解释为不同的编码(为了记录,如果可能的话你应该避免让自己处于数据中混合编码的位置)你'将必须自己将字节从流中拉出,然后使用适当的编码转换字节,这样您就可以确保只拉出您想要的字节的确切部分,而不是更多。
我正在使用有限状态机读取超大文件。不是多线程,不会有线程安全问题
包含3种内容:
- 二进制数,表示后面字符串的长度,一个字符计为1
- ANSI,一个字符占用1~2个字节
- UTF-8,一个字符占用1~4个字节
我发现
目前,我正在使用 StreamReader, but the CurrentEncoding 属性 无法更改,一旦 StreamReader 被初始化。
所以我也尝试在同一个 Stream:
上重新创建 StreamReaderreader = 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
奇怪又有趣
流 reader 将缓冲它们正在读取的基础流中的内容,这就是导致您出现问题的原因。仅仅因为您从 reader 中读取了一个字符并不意味着它只会从基础流中读取一个字符。它会用字节填充一个 while 缓冲区,然后从缓冲区中给你一个字符。
如果你想从流中读取值并将字节的不同部分解释为不同的编码(为了记录,如果可能的话你应该避免让自己处于数据中混合编码的位置)你'将必须自己将字节从流中拉出,然后使用适当的编码转换字节,这样您就可以确保只拉出您想要的字节的确切部分,而不是更多。