java utf 8标准输出,Java输出流对UTF-8编码的处理

最近在修改一个使用Window 给FTP服务器上传中文路径的问题,头疼了很久。

从Windows读取到的字符在遇到中文个数为奇数的时候,路径会被部分识别为乱码。而中文个数为偶数个,则能正常识别出来。

以下是在网上看到某位大牛分析的原因,看了才知道,原来是java输出流搞的鬼。

引用:

最近被utf-8搞得各种头痛。差点就要练出肉眼看二进制编码的火眼金睛。先举个今天遇到的小问题吧。

java用gbk方式写入的文件,似乎有个特性,是会自动把gbk编码中不能识别的0×0这个字节,替换成”?”,也即0x3F。这原本也没什么,但当他读取utf8文本并重新写入新的文件的时候,就会出现偏差。

众所周知,utf8编码的英文和符号部分是同ASCII编码兼容的。同时,在大多数中文中,很少出现0×0这样的字节。因此,用ASCII硬写utf8编码的中英混合文字,然后这个文件再用utf8的方式打开,运气好的话居然可以侥幸蒙混过关,毫无错误。然而,一旦文字中出现了带有0×0字节的utf8编码,就没那么侥幸了。

例如“个性”的性字,其unicode编码为0×6027, 翻译成utf8的话:

60 27

01100000 00100111

[1110]0110 [10]000000 [10]100111

E6 80 A7

这里用方括号标识了utf8的字节头,方便辨识。在windows上是使用小端序,所以实际的序列会是这样:

0110 1110 0000 1000 0111 1010

这里第三个字节出现了0×0,悲剧发生了,被java的流输出不知怎么就那么智能替换成了”?”

0110 1110 1111 0011 ...

6 E F 3

结果这里就乱码了。打出来内容一团糟。变成“个?”。

另外一个曾让我头疼一天的问题,就是根据utf8编码规则,并不会出现0xC0 0×80这个双字。因为如果按照编码规范

0xC0 0x80

[110]0 0000 [10]00 0000

0000 0000

这根本就是0×0嘛!不可能编码成这个样子的。wiki上查了半天才发现,原来这个又是windows的专有解决方案。完全是windows系统一厢情愿,想要区别于一般的ASCII文本而作的别扭事。结果这样的文本想要插入到mysql数据库时,就会被数据库认为是不合理的utf8编码而被冷冷拒绝! 所以整理utf8的编码问题,有时候还是要一直看到二进制上面来,这样问题发生在哪里也就会比较清楚,该怎样解决就不再像是霰弹枪编程,左试右试都不知道哪里出错了哟。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值