我在将一个UTF8字符串从c套接字发送到java套接字时遇到了一些麻烦。 以下方法可以正常工作:
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream(), "UTF8"));
main.title = in.readLine();
但是我需要一个int java.io.InputStream.read(byte[] b, int offset, int length)
方法,而BufferedReader不存在这个方法。所以我试着采用DataInputStream
DataInputStream in2 = new DataInputStream(socket.getInputStream());
但它读到的一切都只是垃圾。
然后我尝试使用readLine()
中的DataInputStream
方法,但这并没有给我正确的UTF8字符串。
你看到了我的困境。我不能为一个InputStream使用两个读卡器吗?或者我可以转换DataInputStream.readLine()
结果并将其转换为UTF8吗?
谢谢, 马丁
答案 0 :(得分:7)
我们从design of the UTF-8 encoding了解到,值0x0A
的唯一用途是LINE FEED('\n'
)。因此,您可以阅读,直至找到它:
/** Reads UTF-8 character data; lines are terminated with '\n' */
public static String readLine(InputStream in) throws IOException {
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
while (true) {
int b = in.read();
if (b < 0) {
throw new IOException("Data truncated");
}
if (b == 0x0A) {
break;
}
buffer.write(b);
}
return new String(buffer.toByteArray(), "UTF-8");
}
我假设您的协议使用\n
作为行终止符。如果不是 - 那么,指出你要写的约束通常是有用的。
答案 1 :(得分:3)
NOT 在同一个InputStream上使用BufferedReader和DataInputStream !!我这样做了,并花了几天时间试图找出我的代码破坏的原因。 BufferedReader可以读取比从中提取的更多内容到其缓冲区中,导致我应该使用DataInputStream读取的数据“在BufferedReader”中的情况。这导致数据丢失,导致我的程序“挂起”等待它到达。
答案 2 :(得分:1)
我相信你不应该与BufferedReader
和DataInputStream
不匹配。 DataInputStream
也有readLine()
,所以请使用它。
而另一个评论。我不确定这是一个问题,但避免多次调用socket.getInputStream()
。做一次,然后根据需要使用其他流和读取器包装它。
答案 3 :(得分:1)
我是否正确理解您在相同的“对话”中同时发送文本和二进制数据?为同一输入流创建两个读取器应该没有问题。问题是知道何时(以及多少)阅读哪个读者。当您从它们读取时,它们将消耗(并推进)基础流,因为您具有混合类型的数据。您可以将流读取为字节,然后在代码中显式转换字节(新字符串(字节,“UTF-8”)等)。或者你可以将你的通信分成两个不同的插座。