-
Notifications
You must be signed in to change notification settings - Fork 34
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
GBK<->UTF8 互转问题: Maven checkstyle输出乱码 #26
Comments
@azige 有个不明白的是为啥utf-8的命令行会输出带乱码的中文. 请问能把 |
只是把命令行改成了UTF-8而已,系统本身的环境还是GBK的 |
发现不少网上分析GBK<->UTF8互转出现乱码的文章里都提到偶数OK,奇数有问题的说法. 其实不尽然. 比如此文提到的"姓名"的三个双字节段恰好都是合法的GBK字符[e5 a7] [93 e5] [90 8d]因此没有被破坏. 只要UTF8的字节码中有GBK中不合法的字符, 就会有问题. 比如我们碰到的"开始". 初步分析已经整理在program-in-chinese/junit4_in_chinese#12 (comment) 还有一些细节要探究, 然后是针对这个插件问题的对策. |
看起来checkstyle的Logger里是按照UTF8编码输出信息的:
试了把 |
找到一个久远的中文部分乱码问题, 感觉应该也是类似的转码过程由于编码之间不兼容导致的, 就是不知道具体转变过程. 后来看到JDBC连接MySQL抛出异常信息乱码, 才试出了这个可能的过程, 输出同样的乱码
以后遇到这种部分乱码的问题, 考虑用个宽度搜索在所有编码里找可能的转变路径, 才能生成同样的乱码 hehe |
阶段小结已发在都市传说: "部分"中文出现乱码. |
@program-in-chinese/all 召唤集体智慧应对~~. 插件作者回复说原因是错误信息的保存文件格式是UTF8. 感觉有两个问题:
|
说一下本人知道的事
windows-1252 没有深入了解过,尝试了一下看来它会对无法处理的字节序列造成某种程度的破坏。不过"中国从前有个传说"那个问题看起来还是因为 iso-8859-1 和 windows-1252 的一些码位不同导致转换出错而破坏了原本的字节序列 那个插件的问题果然跟本人想的一样原作者是直接用 UTF-8 来写字节的啊,虽然意图没搞懂,但是这样在非 UTF-8 的控制台里自然是会乱码的 |
我也看到不少文章提到奇数有问题, 偶数没问题. 其实偶数个字符也可能有问题. 原因详见program-in-chinese/junit4_in_chinese#12 (comment). 刚发现更好的例子是"开始": https://gist.github.com/nobodxbodon/f01a6853ff236703ed2751bd2cf20848
iso-8859-1没有 我也还不明白为何用UTF8编码. 如果系统不是UTF8编码, 那么输出的时候似乎肯定会有问题. 听作者回复的意思好像是为了确保读取UTF8格式的资源文件(messages_x.properties)的时候不会有问题. 但是我的感觉是已经从文件中读出来了(Java的String)之后就应该依赖系统编码. |
看来 Java 的 GBK 和 windows-1252 解码不存在的码位的时候在Java内部就转换成 \uFFFD 了,而 \uFFFD 再编码就会变成 0x3f(问号?还真是简单易懂) 可以试试这个例子就会发现惊喜了
|
@azige 结论是...? 既然Java的String用的是UTF16编码, 输出时的编码和资源文件格式应该完全无关了吧? 你觉得#26 (comment) 之外还有什么解决方案吗? |
嗯之前的 #26 (comment) 本人只是讨论一下错误的反复转码导致源字节流被破坏的成因。关于 checkstyle 插件,本人还没深入去研读过源代码,但是 maven 的日志记得只能输出字符串,如果 checkstyle 自己的日志模块输出 UTF-8 字节流的话,必然要在输出到 maven 日志的时候又要转换回字符。那部分不知道使用了何种编码来转换,而源字节流被破坏的问题可能就是来自这个地方。 |
@azige 不好意思忘说了, 我之前好像找到了它按照UTF8读取properties文件的地方, 详见checkstyle/checkstyle@702a1a9#commitcomment-24945064
之前没有想到这个问题...但是它最后输出的时候应该用的是默认系统编码吧, 详见checkstyle/checkstyle#3569 (comment):
|
我之前就是看到他这个 Logger 然后确认他是输出了 UTF-8 字节流的。 你能取到 |
@azige 不好意思我蒙圈了...你的二重转换和我之前的例程的区别就是多显示了Java的UTF16内码吧? |
|
呃抱歉忘记看那边了,那看起来问题已经能确认了?
|
抱歉这部分没注意看,但是记得 properties 文件按 Java 的规范的是只使用 iso-8859-1,此字符集以外的字符都要转义。而且这里跟日志输出乱码关系应该不是很大吧 |
@azige checkstyle开发组已开始对这个issue进行深入: checkstyle/checkstyle#3569 (comment) 有个问题, 中文windows的系统编码默认是GBK吗? 手边没有中文版windows来确认. 看到这个Windows为什么用GBK而不是UTF-8?, 其中提到windows内码是UTF-16. 那么这个issue的根源其实是, 中文windows命令行默认使用的编码格式是GBK吗? |
客观条件限制, 暂不深究. 如发现此确为冰山一角, 再作投入. |
Update 2023: 我规避这个问题的办法是设置checkstyle的默认locale到en_US,让它输出的日志都是英文。在 <module name="Checker">
<property name="localeLanguage" value="en" />
<property name="localeCountry" value="US" />
.... |
您好,您的邮件已收到,会尽快处理回复您!
|
下面摘自 @azige的 program-in-chinese/junit4_in_chinese#11 (comment)
感觉值得探究一下. 这种编码格式不匹配的问题可能会比想象中的更普遍, 如果中文windows的默认格式是GBK的话.
The text was updated successfully, but these errors were encountered: