为了账号安全,请及时绑定邮箱和手机立即绑定

Java InputStream 读取语言环境依赖?

Java InputStream 读取语言环境依赖?

偶然的你 2022-05-25 16:44:29
我有客户端服务器应用程序。客户端(C++ 应用程序)正在发送 UTF8 编码的字符串,而服务器(Java 应用程序)正在通过套接字端口通信读取这些字符串。如果服务器托管在具有语言环境 CP-1252 的 Windows 操作系统上,我在读取服务器端的字符串时会遇到问题。这是伪代码private transient Socket socket = null;private transient InputStream in = null;private transient OutputStream out = null;socket = new Socket(server, port);out = socket.getOutputStream();in = socket.getInputStream();Socket 和 InputStream 在一些不同的函数中初始化,读取实际字符串如下函数所示:ReadString(){    byte[] backbytes = new byte[2048];    {        if ((c = in.read(backbytes)) > 0) {            if (debug)                logger.trace("Read " + c + " bytes");            total = total + c;            char[] convertedChar = new char[backbytes.length];            int[] convertedInt = new int[backbytes.length];            for(int i=0;i < backbytes.length;i++){                convertedChar[i] = (char) backbytes[i];                convertedInt[i] = (int) backbytes[i];            }            logFilePrint.print("Read string as : " + new String(backbytes, 0, c) + " and the converted char[] of byte[] is : ");            printArray(logFilePrint, convertedChar);            logFilePrint.print(" and converted int[] is : " );            printArray(logFilePrint, convertedInt);            logFilePrint.flush();            sb.append(new String(backbytes, 0, c));        } else {          break;        }    }}某些 Unicode 字符(例如“私”或“の”)会出现此问题。如果我对这些字符执行上述代码,我会得到输出将字符串读为:ç§?ã? byte[] 转换后的 char[] 为:[, ￧, ᄃ, ?,  ̄, ?,] 转换后的 int[] 为:[, -25, -89, 63, -29, 63, -82, ]但是,如果我通过使用“-Dfile.encoding=UTF-8”将 JVM 的字符集设置为 UTF8 来更改服务器编码,我会得到以下输出:将字符串读为:私の,byte[]转换后的char[]为:[, ￧, ᄃ, チ,  ̄, チ, ᆴ] 转换后的int[]为:[, -25, -89, -127, -29, -127, -82,]非 UTF8 模式下的问题似乎与字节“0x81”的字符有关。敌人例如字符'私'有UTF-8编码'0xE7 0xA7 0x81'和'の'有UTF-8编码'0xE3 0x81 0xAE'据我了解,InputStream“in.read(backbytes)”只是读取发送的数据字节。为什么在 JVM 字符集是 UTF-8 和非 UTF8 的情况下读取字节会受到影响?函数“读取”语言环境是否依赖?
查看完整描述

1 回答

?
慕尼黑5688855

TA贡献1848条经验 获得超2个赞

您选择的构造函数String(byte[] encoded, int offset, int length)使用默认平台编码将字节转换为字符。它显式地取决于它运行的环境。

对于可移植代码来说,这是一个糟糕的选择。对于网络应用程序,明确指定要使用的编码。您可以将其作为网络协议的一部分进行协商,或者指定一个有用的默认值,如 UTF-8。

有多种 API 可以对文本进行编码和解码。例如,String(byte[] encoded, int offset, int length, Charset encoding)可以像这样使用 String 构造函数:

String str = new String(backbytes, 0, c, StandardCharsets.UTF_8);


查看完整回答
反对 回复 2022-05-25
  • 1 回答
  • 0 关注
  • 102 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信