带有UTF8的DataInputStream和readLine()

时间:2011-06-16 11:08:40

标签: java utf-8

我在将一个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吗?

谢谢, 马丁

4 个答案:

答案 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)

我相信你不应该与BufferedReaderDataInputStream不匹配。 DataInputStream也有readLine(),所以请使用它。 而另一个评论。我不确定这是一个问题,但避免多次调用socket.getInputStream()。做一次,然后根据需要使用其他流和读取器包装它。

答案 3 :(得分:1)

我是否正确理解您在相同的“对话”中同时发送文本和二进制数据?为同一输入流创建两个读取器应该没有问题。问题是知道何时(以及多少)阅读哪个读者。当您从它们读取时,它们将消耗(并推进)基础流,因为您具有混合类型的数据。您可以将流读取为字节,然后在代码中显式转换字节(新字符串(字节,“UTF-8”)等)。或者你可以将你的通信分成两个不同的插座。