我正在尝试从二进制流中读取数据,其中一部分应该被解析为UTF-8。
直接将InputStream
用于二进制数据,并在其顶部使用InputStreamReader
用于UTF-8文本不起作用,因为读者将提前读取并弄乱后续二进制数据,即使它被告知读取最多n
个字符。
我发现这个问题与Read from InputStream in multiple formats非常相似,但是提出的解决方案特定于HTTP流,这对我没有帮助。
我想把所有东西都读成二进制数据,然后将相关的部分转换成文本。但我只有字符数据的长度信息,而不是字节。因此,我需要从流中读取字符的东西才能知道编码。
有没有办法告诉InputStreamReader不要读取比读取给定数量的字符所需的更多?或者是否有一个支持二进制数据和带编码的文本的阅读器,可以在这些模式之间切换?
答案 0 :(得分:2)
我认为你不应该使用StreamReader。读者处理文本但你一起处理文本和二进制数据。
没有办法。您必须自己读取二进制缓冲区并解释您的格式,即找到文本提取字节的位置并将它们转换为String。
为简化此任务,我建议您创建自己的类(比如说ProtocolRecord。)它应该是Serializable。它将包含您的所有字段。 现在您有两个选择:
(1)简单 - 使用java序列化机制。在这种情况下,您只需要使用DataInputStream包装您的流以进行读取,并使用DataOutputStream进行写入,然后读取/写入您的对象。这种方法的缺点是你无法控制你的协议。
(2)自己实现方法readObject()和writeObject()。现在使用DataInputStream和DataOutputStream,如上所述。 在这种情况下,您必须实现序列化协议,但至少它已封装到您的类中。
它认为DataInputStream是您所需要的。
答案 1 :(得分: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();