这是我在网上查到的一段资料:
分析一下你的”乱码”到底是什么编码。这个其实不难,比如
System.out.println(testString);
这一段出现了乱码,那么不妨用穷举法猜测一下它的实际编码格式。
System.out.println(new String(testString.getBytes(”ISO-8859-1″),”gb2312″));
System.out.println(new String(testString.getBytes(”UTF8″),”gb2312″));
System.out.println(new String(testString.getBytes(”GB2312″),”gb2312″));
System.out.println(new String(testString.getBytes(”GBK”),”gb2312″));
System.out.println(new String(testString.getBytes(”BIG5″),”gb2312″));
等等,上述代码的意思是用制定的编码格式去读取testString这个”乱码”,并转换成gb2312(此处仅以中文为例)
然后你看哪一个转换出来的结果是ok的,那就然后我自己编了个简单的测试程序如下:public class Test {
public static void main(String[] args) {
// TODO Auto-generated method stub
String testString = "夏斌";
try {
System.out.println(new String(testString.getBytes("ISO-8859-1"),"gb2312"));
System.out.println(new String(testString.getBytes("UTF8"),"GB2312"));
System.out.println(new String(testString.getBytes("GB2312"),"GB2312"));
System.out.println(new String(testString.getBytes("GBK"),"gb2312"));
System.out.println(new String(testString.getBytes("BIG5"),"gb2312"));

} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}}发现gb2312,和gbk显示正常,但是有一点gb2312是兼容gbk的,所以我对上述测试还是有怀疑,于是将第二行
System.out.println(new String(testString.getBytes("UTF8"),"GB2312"));改成
System.out.println(new String(testString.getBytes("UTF8"),"UTF8"));
结果可以正常显示
我又将第三行
System.out.println(new String(testString.getBytes("GB2312"),"GB2312"));改成
System.out.println(new String(testString.getBytes("GB2312"),"utf8"));
结果显示乱码
我就糊涂了,用utf8或gb2312或gbk等读取字符串,再转换成相同的编码就可正常显示,但是用一种编码读取字符串,用不同的编码转换,现实就不正常,如此的话,就没法检验你的字符串是什么编码了啊,请高手指点一二,谢谢!

解决方案 »

  1.   

    相同的实验我也做过,我有自己的理解方式,至于正不正确我就不知道了。
    首先在计算机中一个字符串在计算机中的确是以某种方式来储存,但是当你用getByte()方法获得字节数组的时候,你可以认为是 "夏斌"-->byte[], 而不是内存中的字节数组转化成另一个字节数组。
    所以无论你的字符串在内存中是用什么编码方式存储,你用getByte["GBK"]得到的都是这个"夏斌"对应的字节数组。而你之所以会乱码是因为你的编码,解码不一致。现在再说一下为什么有的乱码用这种方式能回复正常。
    System.out.println(new String(testString.getBytes(”ISO-8859-1″),”gb2312″));
    System.out.println(new String(testString.getBytes(”UTF8″),”gb2312″));
    System.out.println(new String(testString.getBytes(”GB2312″),”gb2312″));
    System.out.println(new String(testString.getBytes(”GBK”),”gb2312″));
    System.out.println(new String(testString.getBytes(”BIG5″),”gb2312″));
    我们用上面那例子继续:
    String testString = "夏斌";
    System.out.println(new String(testString.getBytes("GB2312"),"utf8"));
    你用了GB2312编码,用了UTF-8解码显示肯定乱码。要恢复正常的话就必须在加上一句
    System.out.println(new String(testString.getBytes("utf8"),"GB2312"));
    这样可能就恢复正常了,注意是可能。是否会恢复的关键在于第一次用utf-8解码的时候显示的乱码是否有丢弃一些字节来显示,如果丢弃了话,这就没办法恢复了。
      

  2.   

    上面有句写错了,修改如下:我们用上面那例子继续:
    String testString = "夏斌";
    testString = new String(testString.getBytes("GB2312"),"utf8")
    System.out.println(testString);
    你用了GB2312编码,用了UTF-8解码显示肯定乱码。要恢复正常的话就必须在加上一句
    System.out.println(new String(testString.getBytes("utf8"),"GB2312"));
    这样可能就恢复正常了,注意是可能。是否会恢复的关键在于第一次用utf-8解码的时候显示的乱码是否有丢弃一些字节来显示,如果丢弃了话,这就没办法恢复了。
    我记得如果用"ISO-8859-1"解码过的就没办法恢复了,因为它根本不认识中文。
      

  3.   

    中".getBytes("gbk")
    -42,-48
    中".getBytes("utf-8")
    -28,-72,-83首先字符集对于一个字符来说,可能是用到1、2、3、4个字节,具体由字符集规定
    然后字符集对于同一个字符,也会有自己的字节编码,根据不同的编码可以映射出不同的字就好像上面的例子,同一个中文字,会有不同的字节数,和不同的字节
      

  4.   

    个人觉得这种方法不是正规的判断编码的方法。
    import java.io.UnsupportedEncodingException;
    import java.nio.charset.Charset;public class User {
    /**
     * @param args
     * 
     */
    public static void main(String[] args) {
    // TODO Auto-generated method stub
    String testString = "夏斌";
    byte[] bytes = null;
    try {
    bytes = testString.getBytes("ISO-8859-1");
    System.out.print("ISO-8859-1:\t" + btyeBufToHexStr(bytes) + "\t\t");
    System.out.println(new String(bytes, "GB2312"));

    bytes = testString.getBytes("UTF8");
    System.out.print("UTF8\t\t" + btyeBufToHexStr(bytes) + "\t");
    System.out.println(new String(bytes, "GB2312"));

    bytes = testString.getBytes("GB2312");
    System.out.print("GB2312\t\t" + btyeBufToHexStr(bytes) + "\t");
    System.out.println(new String(bytes, "GB2312"));

    bytes = testString.getBytes("GBK");
    System.out.print("GBK\t\t" + btyeBufToHexStr(bytes) + "\t");
    System.out.println(new String(bytes, "gb2312"));

    bytes = testString.getBytes("BIG5");
    System.out.print("BIG5\t\t" + btyeBufToHexStr(bytes) + "\t");
    System.out.println(new String(bytes, "GB2312")); } catch (UnsupportedEncodingException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }
    }
    /**
        * 把字节数组转换成16进制字符串
        * @param bArray
        * @return
        */
    public static String btyeBufToHexStr(byte[] bArray) {
        StringBuffer sb = new StringBuffer(bArray.length);
        char[] base = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
        for (int i = 0; i < bArray.length; i++) {
         sb.append(base[(0xff & bArray[i]) >>> 4]);//高位
         sb.append(base[bArray[i] & 0xf]);//低位
        }
        return sb.toString();
    }}你执行下这段代码就知道了。 注意看打印的字节数组
      

  5.   

    System.out.println(new String(testString.getBytes("utf8"),"GB2312"));如果这个能够恢复,说明这个乱码原本的编码方式是GB2312却用UTF-8来解码。
      

  6.   

    你看的资料应该是这个意思。 给定一个字节数组,或字节流bytes,我们可以判断这个bytes是什么编码方式。即
    byte[] bytes = getBytes()//在流里取得文字的编码
    System.out.println(new String(bytes, ”ISO-8859-1″));
    System.out.println(new String(bytes, ”UTF"));
    System.out.println(new String(bytes,”gb2312″));
    System.out.println(new String(bytes,”gbk″));
    System.out.println(new String(bytes,”big5″));
    这样就可以取得那段文字的编码。