Mik*_*e Q 7 .net c# binaryreader
我遇到了我认为BinaryReader.ReadChars()方法的问题.当我在原始套接字NetworkStream周围包装BinaryReader时偶尔会出现流损坏,其中正在读取的流不同步.所讨论的流包含二进制序列化协议中的消息.
我已将此跟踪到以下内容
我认为发生的事情如下(在下面的例子中)
序列化代码试图解组下一个项目并因为流损坏而呱呱叫.
char[] buffer = new char[3];
int charIndex = 0;
Decoder decoder = Encoding.BigEndianUnicode.GetDecoder();
// pretend 3 of the 6 bytes arrives in one packet
byte[] b1 = new byte[] { 0, 83, 0 };
int charsRead = decoder.GetChars(b1, 0, 3, buffer, charIndex);
charIndex += charsRead;
// pretend the remaining 3 bytes plus a final byte, for something unrelated,
// arrive next
byte[] b2 = new byte[] { 71, 0, 114, 3 };
charsRead = decoder.GetChars(b2, 0, 4, buffer, charIndex);
charIndex += charsRead;
Run Code Online (Sandbox Code Playgroud)我认为root是.NET代码中的一个错误,它使用charsRemaining*bytes/char每个循环来计算所需的剩余字节数.由于在解码器中隐藏了额外字节,因此该计算可以关闭一个,从而导致从输入流中消耗额外的字节.
这是有问题的.NET框架代码
while (charsRemaining>0) {
// We really want to know what the minimum number of bytes per char
// is for our encoding. Otherwise for UnicodeEncoding we'd have to
// do ~1+log(n) reads to read n characters.
numBytes = charsRemaining;
if (m_2BytesPerChar)
numBytes <<= 1;
numBytes = m_stream.Read(m_charBytes, 0, numBytes);
if (numBytes==0) {
return (count - charsRemaining);
}
charsRead = m_decoder.GetChars(m_charBytes, 0, numBytes, buffer, index);
charsRemaining -= charsRead;
index+=charsRead;
}
Run Code Online (Sandbox Code Playgroud)
我不完全确定这是一个错误还是仅仅是对API的滥用.为了解决这个问题,我只是计算自己需要的字节数,读取它们,然后通过相关的Encoding.GetString()运行byte [].然而,这不适用于像UTF-8这样的东西.
有兴趣听听人们对此的看法以及我是否做错了.也许它会为下一个人节省几个小时/几天的繁琐调试.
编辑:发布以连接连接跟踪项目
我已经重现了您提到的问题BinaryReader.ReadChars。
尽管开发人员在编写流和解码器等内容时始终需要考虑先行,但这似乎是一个相当重要的错误,BinaryReader因为该类旨在读取由各种类型的数据组成的数据结构。在这种情况下,我同意ReadChars在读取内容时应该更加保守,以避免丢失该字节。
直接使用的解决方法没有任何问题Decoder,毕竟这是ReadChars幕后的工作。
Unicode 是一个简单的例子。如果您考虑任意编码,那么当您传递字符计数而不是字节计数时,实际上没有通用的方法可以确保消耗正确的字节数(考虑不同长度的字符和涉及格式错误的输入的情况)。因此,避免BinaryReader.ReadChars读取特定字节数提供了更稳健、更通用的解决方案。
我建议您通过http://connect.microsoft.com/visualstudio将此问题提请 Microsoft 注意。
| 归档时间: |
|
| 查看次数: |
3549 次 |
| 最近记录: |