今天研究了一下,记录下来
中间用的是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,这个的接口写的不好,蛮难用的
参考,
我改了一下,
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); }