2009年6月19日金曜日

Java detect Encoding for Japanese

javaにはエンコード自動認識が標準ではなかったので、探し回った。
* jchardet
* juniversalchardet
などが見つかったけど、とりあえず、標準で逃げる方法。

  1. private final List<CharsetDecoder> decoders;  
  2.  {  
  3.  // 色々試した結果、この順序が必須  
  4.  String[] names = new String[] { "ISO-2022-JP""EUC-JP""UTF-8",  
  5.    "windows-31j" };  
  6.  decoders = new LinkedList<CharsetDecoder>();  
  7.  for (String name : names) {  
  8.   decoders.add(Charset.forName(name).newDecoder());  
  9.  }  
  10. }  
  11. public Charset detectEncoding(byte[] bytes) throws Exception {  
  12.  for (CharsetDecoder d : decoders) {  
  13.   try {  
  14.    d.decode(ByteBuffer.wrap(bytes));  
  15.   } catch (CharacterCodingException e) {  
  16.    continue;  
  17.   }  
  18.   return d.charset();  
  19.  }  
  20.  throw new IllegalArgumentException("デコードできませんでした。");  
  21. }  
  22.   
  23. public void testDetectEncoding() throws Exception {  
  24.  String[] samples = new String[] { "平""カ""1""ひ""b", };  
  25.  for (String s : samples) {  
  26.   assertEquals("windows-31j", detectEncoding(s.getBytes("sjis")).toString());  
  27.   assertEquals("UTF-8", detectEncoding(s.getBytes("utf-8")).toString());  
  28.   assertEquals("EUC-JP", detectEncoding(s.getBytes("euc_jp")).toString());  
  29.   assertEquals("ISO-2022-JP", detectEncoding(s.getBytes("jis")).toString());  
  30.  }  
  31. }