【问题标题】:BlackBerry UTF-8 InputStreamReader on Socket issueBlackBerry UTF-8 InputStreamReader 上的套接字问题
【发布时间】:2011-09-03 01:52:41
【问题描述】:

我正在尝试使用套接字从服务器读取响应,并且信息是 UTF-8 编码的。我将来自套接字的 InputStream 包装在 InputStreamReader 中,并将编码设置为“UTF-8”。

由于某种原因,似乎只读取了部分响应,然后读取仅挂起大约一两分钟,然后结束。如果我将 InputStreamReader 上的编码设置为“ISO-8859-1”,那么我可以立即读取所有数据,但显然并非所有字符都正确显示。

代码如下所示

socketConn = (SocketConnection)Connector.open(url);
InputStreamReader is = new InputStreamReader(socketConn.openInputStream(), "UTF-8");

然后我通读了标题和内容。内容被分块,我读取每个块大小的行(从十六进制转换为十进制)以知道要读取多少。

我不了解使用这两种编码读取的差异以及它可能产生的影响,因为它可以在 ISO-8859-1 下正常工作,并且最终可以在 UTF-8 下工作,只是延迟时间很长。

【问题讨论】:

    标签: java http blackberry utf-8 character-encoding


    【解决方案1】:

    很难找到延迟的原因。

    您可以尝试另一种从网络获取数据的方式:

    byte[] data = IOUtilities.streamToBytes(socketConn.openInputStream());
    

    我认为以上内容应该尽快通过。然后从网络获取字节后,您就可以开始数据处理了。请注意,您始终可以从表示 UTF-8 编码字符串的字节中获取 String

    String stringInUTF8 = new String(bytes, "UTF-8");
    

    更新:查看这篇文章的第二条评论。

    【讨论】:

    • 呃,他说的是 HTTP Transfer-Encoding: Chunked 响应。如果不先剥离块头和换行符,盲目地将其完全放入String 是行不通的。另请参阅en.wikipedia.org/wiki/Chunked_transfer_encoding
    • @BalusC:为了清楚起见 - 我不是在谈论将整个 data 字节数组转换为 String。不!读取数据后,可以对其进行调查(可能用ByteArrayInputStream 包装它是一种方法)并且可以将其中的某些部分转换为字符串。
    【解决方案2】:

    我已经在动态删除块大小,所以我最终做了一些类似于 IOUtilities 答案的事情。我没有使用 InputStreamReader,而是使用了 InputStream。 InputStream 有一个可以填充字节数组的读取方法,因此对于每个块,代码看起来像这样

    byte[] buf = new buf[size];
    is.read(buf);
    return new String(buf, "UTF-8");
    

    这似乎有效,不会造成任何延迟,我可以即时删除有关块的额外信息。

    【讨论】:

    • 一般来说,像这样解码部分 UTF-8 流可能会导致错误。由于每个 UTF-8 字符可能由几个字节组成,因此在解码任意大小的块时,您可能会在一个块的末尾得到一个字符的第一部分,而在下一个块的开头该字符的其余部分,在两个块上给出错误的解码结果。在您的特定情况下,您知道每个块的大小,并且保证它们可以正确解码,因此应该可以正常工作。嗯,是的......我希望这是有道理的:)
    • 确实有道理!谢谢,这是我可能需要注意的极端情况。
    猜你喜欢
    • 1970-01-01
    • 2019-08-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多