DB2含重音字符数据通过Java写入CSV出现乱码如何解决
乱码问题定位流程
- 校验数据读取阶段编码是否正确:优先确认DB2 JDBC连接参数是否包含编码配置,DB2的JDBC连接需要显式指定
useUnicode=true和characterEncoding=utf-8,示例连接串:jdbc:db2://<host>:<port>/<dbname>:useUnicode=true;characterEncoding=utf-8;。读取到数据后直接打印目标字符的字节值做校验:Ý的UTF-8编码为0xC3 0x9D,如果读取到的字节不符合该值,说明读数据阶段已经出现乱码,和CSV写入逻辑无关。 - 校验CSV写入阶段编码是否正确:所有文件输出流必须显式指定UTF-8编码,不要使用JVM默认编码,示例写法:
new OutputStreamWriter(new FileOutputStream("output.csv"), StandardCharsets.UTF_8)。如果读取阶段字节正常,写入后文件字节异常,说明是写入阶段编码配置错误。 - 校验CSV打开工具的解码逻辑:如果写入后的文件字节校验正常,用Excel打开后出现乱码,是Excel默认使用系统编码(比如GBK、ISO-8859-1)解析UTF-8无BOM文件导致的,不属于代码逻辑问题。
对应解决方案
- 读取阶段乱码修复
- 补充JDBC连接的编码参数
- 若DB2服务端默认使用单字节编码(如ISO-8859-1)存储数据,读取后需要显式转码:
String correctStr = new String(rawStr.getBytes(StandardCharsets.ISO_8859_1), StandardCharsets.UTF_8);
- 写入阶段乱码修复
- 所有文件IO操作强制指定UTF-8编码,禁止使用无编码参数的Writer、OutputStream实现类
- 若需要兼容Excel打开CSV的场景,在写入内容前先写入UTF-8 BOM头:
FileOutputStream fos = new FileOutputStream("output.csv"); fos.write(new byte[]{(byte) 0xEF, (byte) 0xBB, (byte) 0xBF}); OutputStreamWriter osw = new OutputStreamWriter(fos, StandardCharsets.UTF_8);
- 工具解码兼容
- 无需兼容Excel的场景,直接用VS Code、Notepad++等支持自定义编码的工具打开CSV即可正常显示
- 需兼容Excel的场景按上述方案写入BOM头即可
本次出现的
POKORNÝ转为POKORNÃ是典型的UTF-8双字节字符被按单字节编码拆分解析的特征:Ý的UTF-8首字节0xC3对应ISO-8859-1的字符就是Ã,只要找到错误的解码节点修正即可。
内容的提问来源于stack exchange,提问作者Pradeep
相关产品推荐
相关产品推荐

