java读取文件中文_java字符流读取中文文件问题

0,你需要的知识储备,字符集? 字符编码? 我假设你已经知道了这些

1,对于BigInteger.valueOf(ch).toByteArray() 请查看java.math.BigInteger#toByteArray API文档说明,有详细介绍,它说明了返回的bytes跟平常的不同之处

2,那么现在就剩下,int,char,和文件字节的疑问了

3,fr.read 根据文件的编码格式读取文件中第一个字符,例如文件编码是utf8,由于utf8变长存储数据,因此读取的文件字节长度可能不一样,从1--4个字节不等,

Unicode符号范围 | UTF-8编码方式

(十六进制) | (二进制)

0000 0000 0000 007F

0xxxxxxx 127

0000 0080 0000 07FF

110xxxxx 10xxxxxx 2047

0000 0800 0000 FFFF

1110xxxx 10xxxxxx 10xxxxxx 65535

0001 0000 0010 FFFF

11110xxx 10xxxxxx 10xxxxxx 10xxxxxx 1114111

4,中文 你 字,Unicode值为:20320,十六进制为:4f60,二进制为:100 1111 0110 0000

由于 2047< 20320 <65535 ,所以 你 用utf8编码后为三个节 e4bda0(你可使用hex editor 查看这个文件)

5,java读取这个三个字节 e4bda0 ,对应十进制为 228 189 160,

用byte存溢出了,为 -100 -61 -32 二进制为(byte 8位,之前所有高位截取掉):10011100 11000011 11100000,

这8位二进制数中最高位1代表负数,所以变成 -28 -67 -96

6,对于4步骤中的Unicode 20320 如何变成文件字节 e4bda0

参考上面Unicode -> utf8 编码方式

20320 二进制为:100 1111 0110 0000

符合第三个规则来插入,取20320二进制从末尾取值依次插入,代替x

100 11 1101 10 0000

1110xxxx 10xx xxxx 10xx xxxx

======= 插入代替x

11100100 1011 1101 1010 0000

最终结果 1110 0100 1011 1101 1010 0000 转换为十六进制为 e4bda0 ,所以文件字节为它

7,从Unicode字符 20320, 到使用utf8编码存储的文件字节 e4bda0,再到java getbytes 228 189 160,截取末尾8位,最高位标志位,最终输出为-28 -67 -96

你可能感兴趣的:(java读取文件中文)