posts - 0,comments - 0,trackbacks - 0

下面解释一下Java的编码方式,知道了编码方式则乱码将很容易解决。


1:java中byte是以补码表示:http://www.blogjava.net/orangelizq/archive/2008/07/20/216228.html


2 : IO流操作的基本单元

    观看io里面stream的操作,最终有两种:write(int b),write(byte[] bs),读的方式也一样。 其余的均是在这两种方式上进行封装处理。

    由此也能看到文件操作的基本单元bit,而Java的基本单元是字节(byte),一个字节8个bit,字节能表示的范围为[0,255]。而java里面的byte类型的范围是[-128,127],这点必须区分开。


    因此对write(b), write(byte[] bs) 的理解应该以bit的方式去理解,不能以Java中的byte类型去理解。


    OutputStream.write(int b)是将一个字节写入到流中,而不是将int写入流中,即将int所表示的低8位bit写入,高24bit舍去。因此通过write(int b)将一个byte类型的b写入时不会有问题的:

   byte b = (byte)-1;out.write(b); 该转化过程为: btye -> int -> 截取低8位,写入流中。 中间byte->int得到的int的bit序列可能有误,具体请看:http://www.blogjava.net/orangelizq /archive/2008/07/20/216228.html, 但由于最后截取低8位bit,所以最后得到的bit都是正确的。

   同样可以推理出int i = read() 和 byte b =(byte)read(); 由此我们可以看到读写进行的bit处理都是一致的。

   使用IO的这些接口时,不用考虑是int 还是byte类型,直接调用即可。


3: byte,unicode, 编码方式(比如UTF8)之间的关系

unicode 和utf8的关系: http://www.ruanyifeng.com/blog/2007/10/ascii_unicode_and_utf-8.html

Java编码的基本概念:Java采用的编码:unicode,JVM平台默认字符集和外部资源的编码

请参阅: http://www.javaeye.com/topic/311583

    Java中String 是以unicode的方式存储,也就是说一个String的unicode编码是固定的,其unicode表示的byte序列也是固定。
由于存储效率的原因,我们需要使用别的编码方式,比如utf8,那么就需要将unicode的bit序列转化为utf8所表示的bit序列,这要求unicode和utf8之间必须能互相转换。
    因此可以得出:对同一个unicode使用不同的编码方式得到的bit序列将是不一样的。
   

4:乱码的问题:

    一般的数据流程:外部输入 -> Java String -> 外部输出。
    由于IO处理的byte(8个bit)类型,因此该流程应该为:读取外部介质-> 输入的byte序列 ->JVM的unicode -> 输出的byte序列 -> 写到到外部介质
   
    因此乱码的问题,就会出现在两个地方: 输入的byte序列 -> JVM的Unicode 和  JVM的unicode ->输出byte序列

    也就是, 将某中编码的byte序列 转为 unicode 和 将unicode 转化为 某种编码的byte序列。

    如果你不知道是哪种编码和unicode进行互转,比如:将UTF8的byte序列使用GBK的编码方式转化为unicode,那么得到unicode byte序列可能不对,则在unicode字符集中找到字符和原来就很可能千差万别了。

    另外通过new String(byte[] bs)是不指定编码方式,则默认使用jvm的字符编码进行处理。 因此http://www.javaeye.com/topic/311583 指出一定要知道外部系统和JVM的编码方式。


posted on 2010-09-02 13:58 南国咖啡 阅读(1709) 评论(0)  编辑  收藏

只有注册用户登录后才能发表评论。


网站导航: