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

本文关键字:解码 字节 缓冲区 utf 何最好 读取 | 更新日期: 2023-09-27 18:06:31

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

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

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

我意识到我可以通过增加缓冲区大小来降低这种可能性。然而,它发生的可能性很小。我还可以增加缓冲区的大小,这样我遇到的任何XML文档都可以容纳,但我只是想知道是否有另一种解决方案,以某种方式从字节流中检测字符边界的位置。

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

您对问题和陷阱的看法是正确的。

解决方案已经存在:将StreamReader包裹在您的流上,并使用Read()ReadLine()

如果你想要一个DIY的解决方案,你必须看看Encoder状态属性。超出了我的能力范围。

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

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