浙林龙哥

   :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理
最近又复习了一遍字符编码,常用的链接:
UTF-8概念:
http://www.linuxforum.net/books/UTF-8-Unicode.html


Unicode概念:
http://wiki.ccw.com.cn/Unicode

Unicode编码(0000-0FFF):
http://wiki.ccw.com.cn/Unicode%E7%BC%96%E7%A0%81%E8%A1%A8/0000-0FFF


Java中一般来说String存放的是Unicode编码,
JDK1.5中可以用构造函数:
String(byte[] bytes, int offset, int length, String charsetName)
          构造一个新的 String,方法是使用指定的字符集解码字节的指定子数组。
以前有charsetName参数的构造函数过时了.


这次还用到了StringBuffer,它是线程安全的可以修改String的类.
它里边存放的字符也是Unicode编码的,charAt(int index)可以得到索引中存放的Unicode编码的字符,

注意Java里的字符长度与int的长度一样,而不是像C中的char和byte,
当把大于0x80取出来的字符charAt(0)强制转为int时会变成负数,而不是0x80.因此,使用String.getBytes("UTF-8")就会有这样的问题:
charAt(0)是负数,类似于这样:0xFFA1, 本来0xA1转成UTF-8是0xC2 0xA1,现在好了,它把前面的FF也算进来了,于是就转成了另外一个字符.解决方法是charAt(0) & 0xFF

现在读取网络上的字节流,但遇到这样的问题:

流是ISO-8859-1编码的,有这样一串字节: 0xFD 0x71 0x62,使用in.getLine()读取一行,包含上述字节的话,Java会把0xFD 0x71放在一起作为一个char!
于是我就手动将它分开?弄一个StringBuffer,从最后一个字节开始判断,如果 charAt(index) & 0xFF00 > 0,则将低位insert(index, charAt(index) & 0xFF),然后setCharAt(index, (charAt(index) & 0xFF00)>>8)

这样就好了吗?No!你会发现,0xFD 0x71放到String里再用charAt(index)读出来就不是0xFD 0x71了!,那怎么办?
1) 让iLow=chrTemp的低位, iHigh=chrTemp的高位
2) 用new String(new byte[]{(byte) iHigh, (byte) iLow}, 0, 2, "Unicode");构造出一个新的strTemp
3) strTemp.getBytes()得到两个byte,这两个byte才是0xFD, 0x71

    int iLow = chrTemp & 0xFF;
    int iHigh = (chrTemp & 0xFF00) >> 8;
    
    byte[] aryByte = new byte[]{(byte) iHigh, (byte) iLow};
    String strTempUnicode = null;
    try {
     strTempUnicode = new String(aryByte, 0, 2, "Unicode");
     byte[] aryByteResult = strTempUnicode.getBytes();
     
     sb.insert(j+1, (char) (aryByteResult[1] & 0xFF));
     sb.setCharAt(j, (char) (aryByteResult[0] & 0xFF));
    } catch (UnsupportedEncodingException e) {
     // TODO Auto-generated catch block
     e.printStackTrace();
    }
posted on 2007-09-10 00:07  浙林龙哥  阅读(1605)  评论(2编辑  收藏  举报