首先unicode是字符集,保存着字符与16进制数的对应,每个字符都对应这一个编号也就是两个字节的16进制数。而utf-8,gbk这些称为编码方式,其将十六进制数根据具体的算法转化为2进制保存在内存中,一个字符保存在内存中的值不一定是编号。java采用unicode编码保存所有字符,其实就是每个字符在内存中都使用两个字节存储编号,不做转换。
(1)从os文件系统中读取文件的过程:文件是以指定编码保存在系统中,其字节到字符的映射就是编码完成的工作。首先,读取二进制流,以指定编码的方式转化为unicode编码也就是编号,放入内存。读取完毕,如果指定编码错误,同样的二进制流编码体系中没有对应的字符,就以默认字符填充,也就是??之类的。这就是读取乱码的根源。
(2)从java写入os文件系统的过程:将unicode方式保存的16进制编号按照指定编码规范映射为该编码对应的字节流写入文件。
(3)所谓的转码问题就是字符到字节之间的转换,javaio有两大类Reader/Writer直接读取字符,其实也是封装了字节流读取,只是默认使用了系统编码进行从字节到字符的转换;InputStream和OutputStream则读取字节流。两者之间的转化其实就是使用InputStreamReader,OutputStreamWriter时指定转换的编码。