字符编码

Term 1: 编码页(code page):

计算机只懂得数值。编码页就是字符和数值的对照表。如ASCII编码页就是一个很著名的例子,它把英文字母表和一些控制字符映射到一些特定的数值上去。ASCII编码映射了127个字符,因此7位(bit)二进制数足够用来表示127个字符。

  不同的开发商使用不同的编码页,给这带来了混乱。也就是说,同一个日语字符,在一个机器上可能用0x95和0x5c两个字节表示,而在另外的机器的上则可能是0xc9和0xbd。这样一事每次交换数据都要进行一次转换(称为码表转换(charmap conversion)或码集转换(codeset conversion))。为了解决使用不同编码页带来的转换问题,于是Unicode诞生了。Unicode用一些基本的保留字符制定了三套编码方式。它们分别是UTF-8,UTF-16和UTF-32。正如名字所示,在UTF-8中,字符是以8位序列来编码的,用一个或几个字节来表示一个字符。这种方式的最大好处,是UTF-8保留了ASCII字符的编码做为它的一部分,例如,在UTF-8和ASCII中,“A”的编码都是0x41.UTF-16和UTF-32分别是Unicode的16位和32位编码方式。考虑到最初的目的,通常说的Unicode就是指UTF-16。在讨论Unicode时,搞清楚哪种编码方式非常重要。

 Java内核是unicode的,就连class文件也是,但是很多媒体,包括文件/流的保存方式是使用字节流的。 因此Java要对这些字节流经行转化。char是unicode的,而byte是字节. Java中byte/char互转的函数在sun.io的包中间有。

(1)字节和unicode

"你"的gb码是:0xc4e3 ,unicode是0x4f60

    0xc4e3的二进制:

          1100 ,0100 ,1110 ,0011

 

 byte ——〉char

""的gb码是:0xc4e3 ,unicode是0x4f60
String encoding 
= "gb2312";
byte b[] = {(byte)'\u00c4',(byte)'\u003'};
ByteToCharConverter converter 
= ByteToCharConverter.getConverter(encoding);
char c[] = converter.convertAll(b);
for (int i = 0; i < c.length; i++) {
System.out.println(Integer.toHexString(c[i]));
}
结果是什么?
0x4f60

  char ——〉byte

    String encoding = "gb2312";
    
char c[] = {'\u4f60'};
    CharToByteConverter converter 
= CharToByteConverter.getConverter(encoding);
    
byte b[] = converter.convertAll(c);
    
for (int i = 0; i < b.length; i++) {
       System.out.println(Integer.toHexString(b[i]));
    }
结果是什么?
0x00c4,0x00e3

(2) String和byte[] 

string其实核心是char[],然而要把byte转化成string,必须经过编码。string.length()其实就是char数组的长度,如果使用不同的编码,很可能会错分,造成散字和乱码。例如:


String encoding 
= “”;
byte [] b={(byte)'\u00c4',(byte)'\u00e3'};
String str
=new String(b,encoding);


如果encoding
=8859_1,会有两个字,但是encoding=gb2312只有一个字这个问题在处理分页是经常发生。 

 (3) Reader,Writer / InputStream,OutputStream

Reader和Writer核心是char,InputStream和OutputStream核心是byte。但是Reader和Writer的主要目的是要把char读/写InputStream/OutputStream。例如:

文件test.txt只有一个
""字,0xc4,0xe3
String encoding 
= "gb2312";
    InputStreamReader reader 
= new InputStreamReader(new FileInputStream(
        
"text.txt"), encoding);
    
char c[] = new char[10];
    
int length = reader.read(c);
    
for (int i = 0; i < length; i++) {
       System.
out.println(c[i]);
    }


结果是什么?是
""
原文地址:https://www.cnblogs.com/kevinge/p/2047363.html