黑马程序员_字符编码

来源:互联网 发布:中国经济发展数据图表 编辑:程序博客网 时间:2024/05/01 04:56

 ------- android培训、java培训、期待与您交流! ----------

字符的编码问题

字符流的出现是为了方便的操作字符

其实最重要的是它的内部加入了编码表,字符流会自动的进行编码和解码。

ASCII:美国标准信息交换码。

   用一个字节的7位可以表示。

ISO8859-1:拉丁码表

   用一个字节的8位可以表示

GBK:中国的编码表。

Unicode:java中的char就是使用的Unicode编码格式。

UTF-8:最多用三个字节来表示一个字符。

 

 

举个例子,当使用字符流输入字符串”199”的时候, 每个字符都会写入到文件中,由于字符‘1’的统一码是0X0031,所以会根据这个内部的编码表将0x0031转成一个代码。这个编码表可以是任何的编码表,比如在美国,默认的编码方案的ascii 字符‘1’的ascii的 是49,而所以会将0x49写入到对应的文件中,这里就使用了特定的编码方案。

当你再去用字符流读取相应的文件时候,系统会根据你的编码表去解码你对应文件中的各个位对应的二进制位,从而转成统一码,然后转成相应的字符。

 

你会这样去想,如果我们不去使用系统默认的编码方式的话,怎么将字符以特定的编码方式去编码和解码呢?

这时就用到了转换流InputStreamReader和OutputStreamWriter

来将指定的编码格式来编码和解码一个字符。

 

下边来举个例子

OutputStreamWriter osw = new OutputStreamWriter(newFileOutputStream("text.txt"));

        

         osw.write("你好");

         osw.close();

 

这里我们,没有指定编码表,这时自动使用系统自带的编码表。

我这里是utf-8的编码形式。

如果只输入默认形式的编码。我们写一个fileWriter就足够了

也就是上述所讲到的字符流编码的自动转换。

我再次重申一遍,使用OutputStreamWriter是为了改变系统内置的编码类型,如果仅仅是录入字符数据,我们使用系统自带的字符流就可以。

 

例如,在我的机子上使用GBK编码的格式输出的时候,我必须使用这个流,因为我的系统默认为utf-8

当指定用OutputStreamWriterosw = new OutputStreamWriter(newFileOutputStream("text.txt"),"GBK");

 

文本就会出现���乱码的形式。

因为文本拿utf-8的编码表去解码GBK的,所以就有乱码。

 

当然,转换流的强大之处在于可以去更改系统默认的编码表。

也就是上边的方框。

还有一点,文本中写入的其实都是二进制文件,但是为什么打开后是对应的字符呢,是因为文本程序在打开时候,就已经对其二进制进行了解码处理了。

 

编码和解码:其实就是对数据进行转换。

字节边字符:解码

字符边字节:编码

String   -->byte[]   String.getBytes ()

Byte[]---->String new String(Byte[] bytes);

同时可以给其指定编码格式,String  charsets

如果没有指定,按默认的平台编码格式指定。

如果在编码的时候编错,比如将两个中文变为ISO8859-1的形式

String s = "你好";

byte[] arr = s.getBytes("iso8859-1");

这就挂了,这张表根本就不识别中文。编码错误就别再去解了,没有解。编错就没得解。

但是解错还有办法进行弥补。(十分重要)

例如:

String s = "你好";

byte[] bytes = s.getBytes("gbk");    [-60, -29, -70, -61]

String ss = new String(bytes,"iso8859-1");通过(查表)解码后成为ÄãºÃ拉丁文。

byte[] bytes1 = ss.getBytes("iso8859-1");//再次通过解码得到重新的字节码。   得到了[-60, -29, -70, -61]的四个数字。

System.out.println(newString(bytes1,"gbk"));再使用这四个数字去解码。


这里再提一点,就是在web中进行操作的时候,比方说有一个input 输入了汉字给服务器端,也就是将汉字经过utf-8编码后通过字节流的形式传入到服务器端。

但是tomcat默认的编码是iso8859-1。也就是tomcat使用iso8859-1去解码utf-8编码后的字节码。所以得到的是乱码。

 

现在就只能在服务器端将这个乱码先编码(iso8859-1)--》字节码

然后再使用utf-8将其解码

String name1 =newString(name.getBytes("iso8859-1"),"UTF-8");

 

如果使用get提交的时候,必须这么做,如果是post的话,可以使用request.setCharacterEncoding(arg0),则自动帮你转化。

但是也可以将tomcat的码表改成gbk,但是这样不推荐,当一个编码格式为UTF-8的网页通过GBK进行编码的时候,就变为了乱码。

导致客户无法得到。这就必须使用iso8859-1去进行编码了,然后将其发出去的字节码,通过网页进行解码(根据网页的字符类型,浏览器自动进行编码。)。注意,不能使用utf-8编错之后再去使用utf-8解一次。(都是对汉字进行编码与解码)

 

 

联通问题:

由于使用GBK进行编码时候,一个字符对应两个字节。所以联通被编写成4个字节,而在UTF-8中,字符的编码格式可能是一个字节,两个字节,三个字节。其实对于UTF-8编码来说,都加了一个标识头信息。它按照自己的标识头就能知道一次读一个字节呢,还是几个字节呢?

Utf-8的编码规则

 

联通经过GBK编码之后成为的二进制

11000001 10101010  11001101  10101000

产生的二进制形式与UTF-8一致。

记事本去解码去了,就把这个码满足utf-8的形式,就用utf-8去解码了。所以错误了。

 

原创粉丝点击