关于 ASCII , Unicode 和 UTF-8 的概念这里不再赘述,可以通过链接查看它们在维基百科上的定义。
快速入门,推荐阅读阮一峰的博客《 字符编码笔记:ASCII,Unicode 和 UTF-8
》
本文主要介绍Java中对字符是如何存储并读取的
U+5F20
5F20
转换为2进制为 0101 1111 0010 0000
因为 U+5F20
落在 U+0800
~ U+FFFF
区间,可以确定汉字“张”转换成 UTF-8
格式后由 3个字节 组成,按照上面的转换规则,得出 汉字“张”的 UTF-8
编码为 1110 0101 1011 1100 1010 0000
这和我们直接查看"张"的编码是保持一致的(默认编码为UTF-8)
File file = new File(System.getProperty("user.dir") + "/src/main/java/com/dsying/IO/a.txt"); Reader reader = new FileReader(file); System.out.println(reader.read()); // 24352 复制代码
24352的确是汉字“张”的10进制码点
File file = new File(System.getProperty("user.dir") + "/src/main/java/com/dsying/IO/a.txt"); FileInputStream is = new FileInputStream(file); System.out.println(is.read()); // 229 复制代码
229
的16进制表示确实是 E5
,也就是汉字"张”的第1个字节
File file = new File(System.getProperty("user.dir") + "/src/main/java/com/dsying/IO/a.txt"); FileInputStream is = new FileInputStream(file); // 每次读取3个字节 byte[] bytes = new byte[3]; is.read(bytes); System.out.println(Arrays.toString(bytes)); //[-27, -68, -96] 复制代码
为什么bytes里存的是负数,明明第一个字节E5对应的十进制应该是229啊,存的为什么是-27?
这是因为 byte
只能存 1
个字节即 8
个二进制位,也就是 -128 ~ 127
之间的数,byte显然存不下229,发生了溢出
-27再如何转为229?
负数的二进制可由正数的二进制 取反加一
得到
然后再用 1110 0101 & 0xff
最终得到 1110 0101
(高位全部为0)也就是 229
Java中char类型占多少字节?如果是2个字节,为什么有时getBytes().length > 2
放上一张我咨询别人的截图