【问题标题】:DataInputStream and readLine() with UTF8带有 UTF8 的 DataInputStream 和 readLine()
【发布时间】:2011-06-16 11:08:39
【问题描述】:

我在将 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());

但它读取的所有内容都是垃圾。

然后我尝试使用 DataInputStream 中的 readLine() 方法,但这并没有给我正确的 UTF8 字符串。

你看到了我的困境。我不能为一个 InputStream 使用两个阅读器吗?或者我可以将 DataInputStream.readLine() 结果转换为 UTF8 吗?

谢谢, 马丁

【问题讨论】:

  • 我是否正确理解您在同一个套接字上,在同一个“对话”中发送文本和二进制数据?为同一个输入流创建两个阅读器应该没有问题。问题是知道何时(以及多少)阅读哪个读者。当您从它们读取数据时,它们都会消耗(并推进)基础流,因为您有混合类型的数据。您可以将流读取为字节,然后在代码中显式转换字节(new String(bytes, "UTF-8") 等)。或者您可以将通信拆分到两个不同的套接字上。
  • @pap:这很值得回答 ;-)
  • @pap:我同意,发表评论作为答案:)

标签: java utf-8


【解决方案1】:

我们从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 作为行终止符。如果没有 - 好吧,指出您正在写入的约束通常很有用。

【讨论】:

  • 干得好!这就是我需要的!谢谢大家!
【解决方案2】:

在同一个 InputStream 上使用 BufferedReader 和 DataInputStream!我这样做了,并花了几天时间试图弄清楚我的代码为什么会损坏。 BufferedReader 可以读取比您从中提取的内容更多的内容到其缓冲区中,从而导致我应该使用 DataInputStream 读取的数据“在 BufferedReader 中”。这导致数据丢失,导致我的程序“挂起”等待它到达。

【讨论】:

    【解决方案3】:

    我相信你不应该在这里错配BufferedReaderDataInputStreamDataInputStream 也有 readLine(),所以使用它。 还有另一条评论。我不确定这是一个问题,但要避免多次调用socket.getInputStream()。执行一次,然后使用其他流和阅读器根据需要包装它。

    【讨论】:

    • 我尝试使用 DataInputStream 中的 readLine() 方法,但没有得到正确的 unicode 符号。文档说此方法已被弃用:download.oracle.com/javase/1.4.2/docs/api/java/io/…。所以现在我带了两个阅读器 inputStream = socket.getInputStream();数据输入流 = 新数据输入流(输入流); bufferedReader = new BufferedReader(new InputStreamReader(inputStream, "UTF8"));
    • 首先,bufferedReader 读取一些文本。然后 dataInputStream 必须读取一些字节,但它卡住了 read() 方法返回 -1 尽管我发送的字节比 dataInputStream 接收的多。 bufferedReader 是否消耗一些字节? oO
    【解决方案4】:

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

    【讨论】:

      猜你喜欢
      • 2011-08-02
      • 2019-06-02
      • 1970-01-01
      • 2011-08-28
      • 1970-01-01
      • 1970-01-01
      • 2017-03-14
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多