7

我正在尝试从二进制流中读取数据,其中的一部分应该被解析为 UTF-8。

直接使用InputStream二进制数据并InputStreamReader在其上使用 UTF-8 文本不起作用,因为即使被告知读取最多n字符,阅读器也会提前阅读并弄乱后续的二进制数据。

我认识到这个问题与Read from InputStream in multiple formats非常相似,但是那里提出的解决方案特定于 HTTP 流,这对我没有帮助。

我想只是将所有内容作为二进制数据读取,然后将相关部分转换为文本。但我只有字符数据的长度信息,而不是字节。因此,我需要从流中读取字符的东西来了解编码。

有没有办法告诉 InputStreamReader 不要比读取给定数量的字符所需的更远?或者是否有一个阅读器同时支持二进制数据和带有编码的文本,并且可以在这些模式之间动态切换?

4

2 回答 2

2

我认为您不应该使用 StreamReader。读者处理文本,但您同时处理文本和二进制数据。

没有办法。您必须阅读二进制缓冲区并自己解释您的格式,即找到文本提取字节的位置并将它们转换为字符串。

为了简化这项任务,我建议您创建自己的类(比如说 ProtocolRecord。)它应该是可序列化的。它将包含您的所有字段。现在您有 2 个选项:

(1)简单一——使用java序列化机制。在这种情况下,您只需使用 DataInputStream 包装您的流以进行读取,并使用 DataOutputStream 进行写入,然后读取/写入您的对象。这种方法的缺点是您无法控制您的协议。

(2) 自己实现方法 readObject() 和 writeObject()。现在如上所述使用 DataInputStream 和 DataOutputStream。在这种情况下,您确实必须实现序列化协议,但至少它被封装到您的类中。

它认为 DataInputStream 是您所需要的。

于 2011-06-30T07:18:57.640 回答
2

您需要先阅读二进制部分。在您识别需要 UTF-8 解码的部分字节的地方,您需要提取这些字节并对其进行解码。

DataInputStream dis = 
// read a binary type.
int num = dis.readInt();
int len = dis.readUnsignedShort();
// read a UTF-8 portion.
byte[] bytes = new byte[len];
dis.readFully(bytes);
String text = new String(bytes, "UTF-8");
// read some binary
double d = dis.readDouble();
于 2011-06-30T07:31:34.253 回答