JavaIO Stream 返回不同的位

问题描述

@GET
@Path("/hello-message")
@Produces(APPLICATION_JSON)
public Response getMessage() throws Exception {
    char[] array = {'h','e','l','o',2000,3000,9999};
    ChararrayReader chararrayReader = new ChararrayReader(array);
    int c = 0;
    while ((c = chararrayReader.read()) != -1) {
        System.out.println(c + " " + Integer.toBinaryString(c) + " " +(char)c);
    }
    return Response.status(200).entity(chararrayReader).build();
}

当上面的 REST api 被点击时,这就是打印出来的内容

104 1101000 h
101 1100101 e
108 1101100 l
108 1101100 l
111 1101111 o
2000 ߐ 11111010000
3000 101110111000 ஸ
9999 10011100001111 ✏

显然我正在使用 Unicode(数组中的最后 3 个字符),因此,这些是物理位(仅上面的位部分),我认为将通过底层网络传输。

但是,当我收到响应时,我将其作为 InputStream 从 apache HTTP api 中获取

class Test {
    public static void main(String[] args) throws Exception {
        HttpGet httpGet = new HttpGet("http://localhost:80/hello-message");
        CloseableHttpClient httpClient = HttpClients.createDefault();
        CloseableHttpResponse response = httpClient.execute(httpGet);
        InputStream inputStream = response.getEntity().getContent();
        int c = -1;
        while ((c = inputStream.read()) != -1) {
            System.out.println(c + " " + Integer.toBinaryString(c));
        }
    }
}

当我遍历 InputStream 中的字节时,这是我收到的,

104 1101000
101 1100101
108 1101100
108 1101100
111 1101111
223 11011111
144 10010000
224 11100000
174 10101110
184 10111000
226 11100010
156 10011100
143 10001111
  1. 对于 h,e,l,o 的前 5 个字符,API 方法和我收到的响应都具有完全相同的位。

  2. 当超出ASCII限制时,为什么会出现下面的差异, 例如,对于 unicode 2000,

     In API method it printed = 11111010000,In Response it printed = 11011111 (223) followed by 10010000 (144) which clearly doesn't matches above. I expected 11111010000 will be broken into 2 bytes like 00000111 (7) 11010000 (208),but I received something else like,223 and 114.
    

但是当我通读 IoUtils 库时,我得到了正确的响应,

String s = IoUtils.toString(response.getEntity().getContent(),UTF_8);
System.out.println(s);

这将打印与 API 方法返回的字符数组相同的字符串

helloߐஸ✏

这种行为有什么原因吗?流如何将碎片放回原处并形成正确的消息?

解决方法

哇!我真的打了一个很长的问题,为了在下一分钟找到答案,我折腾了一天。

这段 9 分钟的视频太棒了:https://www.youtube.com/watch?v=MijmeoH9LT4