• 已删除用户
童话的爱
童话的爱
发布于 2024-06-17 / 28 阅读 / 0 评论 / 0 点赞

关于Java尽量使用InputStream而不是BufferedReader的问题

如题,本人碰到过一次因使用BufferedReader 的readLine() 导致读取出的文字总是乱码(主要是中文)的问题,场景是在使用TCP协议通讯时,对方返回的字节流在被自动用BufferedReader 读取并转换为字符时转错了,可能大家一般听到的是java默认使用Unicode (Unicode与UTF-8区别见:5分钟,搞清 Unicode 与 UTF-8 的区别 - Liaofy - 博客园 (cnblogs.com))编解码,但可能是具体的编解码字符集的版本未指定导致其无法通过readLine() 方法返回正确解析的字符串,这种用readLine() 解析的字符串有可能会出现下列情况:

{
  "FABC": {
            "%????": "2%",
            "LAN": "3.09db",
            "WAN": "-1",
            "????": "L",
            "????": "3",
            "??????": "0.3"
  }
}

可以看到部分文字是解析出来了但是其他一些文字却被显示成?

一般不直接使用BufferedReader 而直接使用InputStream 获取原始输入流,从流中一点点截取byte 并将其转为字符,最终再拼接为字符串较为合适。目前为止还没bug。(不过如果每次截取的字符串一样且每次都是截取完就去转换成字符串则有可能会出现将一个文字的字节切开导致解码时错误的问题,该问题可以考虑将byte 存入数组中,等到全部读取完毕后再一口气全部转化为指定字符编码的String)

网络响应解析部分的完整代码:

public String streamToString() {
        StringBuilder sb = new StringBuilder();
        Socket socket = SocketUtil.connect(serverAddress, serverPort);
        InputStream inputStream = socket.getInputStream();
        // 不使用这个 reader = new BufferedReader(new InputStreamReader(inputStream));

        byte[] byteArrays = new byte[1024];
        int b;
        while ((b = inputStream.read(byteArrays)) != -1) {
            sb.append(new String(byteArrays, Charset.forName("utf-8")));
            if (sb.toString().contains("end")) {
                break;
            }
        }

        ...

        return sb.toString();
}


评论