Java字符编码问题

    xiaoxiao2024-05-09  134

    今天研究了一下,记录下来

    中间用的是redis,可以使用任意其他的io替代,一样的

     

    Test1

            String s1 = "我要测试";

            String s2 = "I want to test";

            String s3 = "경쟁력, 네이버";

            redis.lpush("testencode", s1);

            redis.lpush("testencode", s2);

            redis.lpush("testencode", s3);

            System.out.println(redis.lpop("testencode"));

            System.out.println(redis.lpop("testencode"));

            System.out.println(redis.lpop("testencode"));

    结果:全部正确

    注解:Java内部也是unicode,所以如果发送和接受端都是Java写的,无需任何转码(前提是发送和接受端的默认编码一致)

            Java在往I/O发送和从I/O接受的时候会默认转码,一般用系统默认的编码,貌似文档本身的编码格式优先级更高

            所以这里发送到时候转成utf-8,接受时再从utf-8转回unicode,所以没有问题

     

    Test2

            String s1 = "我要测试";

            byte[] key = "testencode".getBytes();

            byte[] b1 =  s1.getBytes("gb2312"); //自己转码,而非默认转码

            redis.lpush(key, b1);

            System.out.println(new String(redis.lpop(key),"gb2312"));

            //System.out.println(new String(redis.lpop(key)));

    结果:正确

    注解:由于发送的时候已经转成gb2312,所以接受的时候,必须转回来,如果用默认的(注释掉部分)就会转成默认编码utf-8,就会乱码

     

    前面的转码都是在知道原编码的情况下,但有时在接收端无法知道原来的编码,这是就需要detect编码

    使用JCharDet,这个的接口写的不好,蛮难用的

    参考,http://blog.csdn.net/chenvsa/article/details/7445569

    我改了一下,

    import org.mozilla.intl.chardet.nsDetector;  import org.mozilla.intl.chardet.nsICharsetDetectionObserver;  import org.mozilla.intl.chardet.nsPSMDetector;

    public class CharsetDetector{      private boolean found = false;      private String result;      private int lang = nsPSMDetector.ALL;

        public String[] detectCharset(byte[] bytes) throws IOException      {          String[] prob;          // Initalize the nsDetector() ;          nsDetector det = new nsDetector(lang);          // Set an observer...          // The Notify() will be called when a matching charset is found.          det.Init(              new nsICharsetDetectionObserver(){                     public void Notify(String charset)                  {                      found = true;                      result = charset;                  }              });          int len = bytes.length;          boolean isAscii = true;          if (isAscii){              isAscii = det.isAscii(bytes, len);          }          // DoIt if non-ascii and not done yet.          if (!isAscii){              if (det.DoIt(bytes, len, false));                            }          det.DataEnd();          if (isAscii){              found = true;              prob = new String[] {"ASCII"};          } else if (found){              prob = new String[] {result};          } else {              prob = det.getProbableCharsets();          }          return prob;      }

        public String[] detectChineseCharset(byte[] bytes) throws IOException      {          try{              lang = nsPSMDetector.CHINESE;              return detectCharset(bytes);          } catch (IOException e){              throw e;          }      }

    使用,

    CharsetDetector cd = new CharsetDetector();  String[] probableSet = {};

    try {       probableSet = cd.detectChineseCharset(b1);  } catch (IOException e) {       e.printStackTrace();  }  for (String charset : probableSet)  {      System.out.println(charset);  }

    本文章摘自博客园,原文发布日期:2014-05-14

    最新回复(0)