如何最好地读取和UTF-8解码字节缓冲区?

时间:2011-08-25 07:51:27

标签: c# encoding utf-8 stream

我有Stream生成UTF-8个编码字符串。字符串表示我需要解析的XML文档。该流是从TcpClient获得的。

假设我将流读入大小为64的缓冲区(我知道有点小)。将这些64字节缓冲区直接传递到字符串解码步骤可能会失败,因为某些UTF-8编码字符可能会沿着64字节边界分割。缓冲区可以以字符的前两个字节结束,下一个缓冲区可以包含该字符的最后一个字节。

我现在所做的是连接缓冲区,直到我执行不读取完整64字节的读取,表明我已经读到了某些东西(在我的例子中是一个XML文档)。但是,偶尔,我读取的XML文档正好在64字节边界处结束。在这种情况下,我不知道我可以将字节数组传递给解码步骤(我需要等待下一个文档)。

我意识到我可以通过增加缓冲区大小来降低机会。但是,它总是存在一个很小的机会。我还可以增加缓冲区大小,以便我遇到的任何XML文档都适合,但我只是想知道是否有另一种解决方案,以某种方式从字节流中检测字符边界。

2 个答案:

答案 0 :(得分:2)

你对问题和陷阱是正确的。

解决方案已存在:在您的信息流周围打包StreamReader并使用Read()ReadLine()

如果您确实需要DIY解决方案,则必须查看Encoder状态属性。超越我的能力。

答案 1 :(得分:2)

我相信你的方法在理论上是有缺陷的,即使它在实践中应该总能正常工作:不能保证小于(缓冲区大小)的成功读取表明已经完整地接收到XML文档。 TCP堆栈完全在其权限范围内,一次一个字节地返回文档。将缓冲区大小增加到几KB应该会导致此问题出现。

正确解决上述缺陷也将解决当前问题:在TCP流中的每个XML文档之前添加某种固定长度的头(例如8个字节),其中包含以下文档的长度。您将始终知道何时读取完整标题(因为它是固定大小),并且在您收到整个文档时,您将知道标题。