news 2026/4/23 18:37:14

java 默认字符编码问题

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
java 默认字符编码问题

问题现象:

在进行宝蓝德适配时发现主机的授权信息中客户名称和部门名称展示为乱码, 针对该问题进行分析,现象如下:

分析思路:

分析乱码的原因:

分析获取的该参数的值方法:

publicString getBin(Pointer lic, String column) {

Pointer buf =newMemory(256);

IntByReference bufsize =newIntByReference();

bufsize.setValue(256);

if(INSTANCE.license_get_bin(lic, column, buf, bufsize) < 0) {

return"";

}

byte[] value = buf.getByteArray(0, bufsize.getValue());

returnnewString(value);

}

可以看出就是通过jni函数获取对应字段的byte数组,转换为字符串,通过远程debug连接后,发现获取的字符串,发现确实是乱码, 进一步分析从jni中获取的byte数组列表,得到的数据为[-28, -72, -83, -24, -81, -107, -25, -84, -74, -23, -98, -81, -26, -104, -112], 通过ai分析得到如下结果:

这组byte按 UTF-8解码对应的字符串是:

测试服务器

可用下面代码验证:

byte[] b =newbyte[] {-28, -72, -83, -24, -81, -107, -25, -84, -74, -23, -98, -81, -26, -104, -112

};

System.out.println(newString(b, StandardCharsets.UTF_8));

说明byte数组转换为字符串确实为预期的值,只能说明是new String(value);时使用到java进程的默认字符集导致的即对应的字符集非UTF-8编码

分析默认编码为何非预期UTF-8

需要分析默认的charset的获取方式,阅读Charset的源码中可以看到,是通过读取file.encoding的property获取。

publicstaticCharset defaultCharset() {

if(defaultCharset ==null) {

synchronized(Charset.class) {

String csn = AccessController.doPrivileged(

newGetPropertyAction("file.encoding"));

Charset cs = lookup(csn);

if(cs !=null)

defaultCharset = cs;

else

defaultCharset = forName("UTF-8");

}

}

returndefaultCharset;

}

通过arthas工具,查看问题节点的file.encoding非UTF-8编码,而为ANSI_X3.4-1968类型。

接下来分析file.encoding是如何设置的,通过分析jdk和从AI结合分析,得到在jvm启动时会尝试从本地的locale中获取,会从LC_CTYPE中获取encoding信息,实际实现为en_US.UTF-8 ,设置encoding就是UTF-8 部分(有兴趣的可以设置LC_CTYPE参数,查询file.encoding值)。具体jdk代码如下:

setlocale(LC_ALL,"");

if(ParseLocale(env, LC_CTYPE,

&(sprops.format_language),

&(sprops.format_script),

&(sprops.format_country),

&(sprops.format_variant),

&(sprops.encoding))

在bash中执行locale命令, 获取到的locale输出却是utf-8类型

综合现象和默认值对比,只能是启动java进程的进程上下文中配置的locale被单独设置导致的,在进程启动脚本中添加输出locale的日志,发现确实被修改为POSIX了,非xxx.utf-8.

解决方案:

方案一: 在bes.sh执行启动bes程序前设置locale为UTF-8编码即可。

方案二: 已知会从系统properties中获取,可以加-Dfile.encoding=UTF-8参数的方式设置

总结:

1、为了保障程序的通用性,如果已知字符集时new String, IO流操作场景,最好都配置上字符集

2、程序设计时注意程序设置环境变量或参数对子进程的影响。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/23 18:34:13

Verus:基于 Rust 验证代码正确性,指南助你掌握验证概念与技术!

键盘快捷键 按 ← 或 → 可在各章节间导航&#xff1b;按 S 或 / 能在本书中搜索&#xff1b;按 ? 可显示此帮助信息&#xff1b;按 Esc 则可隐藏此帮助信息。 模式选项包括&#xff1a; 自动明亮模式Rust 模式煤炭模式海军蓝模式Ayu 模式 Verus 教程与参考手册Verus 概述 Ver…

作者头像 李华
网站建设 2026/4/23 18:30:00

告别电脑!用Termux在安卓手机上玩转ADB,实现免Root自动化(保姆级教程)

安卓手机变身ADB控制中心&#xff1a;Termux零门槛自动化实战指南 每次出差都要背着笔记本电脑调试设备的日子该结束了。上周我在机场候机时&#xff0c;仅用一部安卓手机就完成了原本需要电脑才能操作的ADB调试任务——整个过程不到10分钟&#xff0c;周围乘客还以为我在玩游戏…

作者头像 李华
网站建设 2026/4/23 18:29:31

YOLO26精准识别37个猫狗品种(柯基/布偶/哈士奇…)(项目源码+YOLO数据集+模型权重+UI界面+python+深度学习+远程环境部署)

摘要 本文针对宠物猫狗精细品种识别任务&#xff0c;构建了一套基于YOLO26深度学习框架的实时目标检测系统。系统涵盖37个常见猫狗品种&#xff0c;包括12个猫品种和25个狗品种。实验采用包含14,000余张标注图像的数据集&#xff0c;按8:1:1比例划分为训练集、验证集和测试集。…

作者头像 李华
网站建设 2026/4/23 18:29:29

YOLO26汽车损坏检测:mAP50=92.9%,精确率88.5%,召回率89.6%(附10218张数据集)(项目源码+数据集+模型权重+UI界面+python+深度学习+远程环境部署)

摘要 本文基于YOLO26目标检测算法&#xff0c;构建了一套汽车损坏识别检测系统。系统以“Car-Damage”为单一检测类别&#xff0c;旨在对车辆外观损伤&#xff08;如划痕、凹陷、破裂等&#xff09;进行自动定位与识别。训练过程采用10,218张标注图像&#xff0c;验证集包含97…

作者头像 李华