InputStreamReader详解及应用


官方的文档写道是:将字节流变成字符流, 使用默认或指定的字符转换器进行解码, 默认编码是ISO8859_1. 这里最重要的就是字节流和字符流的概念.

我的疑问是不同编码的字节经过各自对应的解码器解码之后得到的字符流是否还和原来的编码有关系, 例如同一段文本分别用utf8和gb2312编码的, 然后InputStreamReader分别用utf8和gb2312解码之后得到的字符串是否是一样的.

从Oracle的文档得知, Java平台使用Unicode存储字符值, 这叫做internal format, 那么前面的假定就是成立的,一段文本的字节形式可以有多种形式,但是转换成字符之后只有一种形式, 就是Unicode形式.与之对比的是windows系统里面的字符编码, Windows的API有两套, 一套是用unicode,另一套是ANSI, 在ANSI中, 内部编码是DBCS, 也就相当于Java中的Unicode.

假设连接MySQL的时候使用的useUnicode和characterEncoding, 显然这个编码是指将字符流写入数据库的时候所用到的编码, 比如数据库表的格式中指定了UTF8编码, 只要在jdbc连接url中指定了utf8 , 就可以正确的将字符流写入数据库, 而数据的格式也将会是utf8.

假如来源数据是gb2312,使用InputStreamReader转换成字符流之后, 在jdbc url中指定utf8编码就可以将数据以utf8的形式保存到数据库中, 事实上, 无论来源的数据是什么格式, 如果要用Java代码来进行分析和处理都必须先转换为字符流,也就是java平台内部表示字符所用的格式.

不过MySQL的有些地方指定的编码不是针对目标数据,而是来源数据, 假如在cmd中输入命令, 而数据库中的数据是utf8 编码的, 而cmd使用是windows代码页, 而不是UTF8 , 为了正确的在cmd窗口中显示数据和插入数据, 必须设置:

set character_set_client = gb2312;
set character_set_connection = utf8;
set character_set_results = gb2312;
这样当像数据库提交数据的时候, MySQL会从gb2312到utf8做一个转换, 当查询数据的时候会做一个相反的转换.