juniversalchardet

juniversalchardet はMozilla Public License 1.1/GPL/LGPLライセンスの文字コード判定ライブラリーです。
日本語ですと、SJIS・JIS・EUC-JP・UTF-8のいずれのコード化を判定してくれます。

私の場合、SRTの字幕形式のファイルを読み込むときに、SJIS・UTF-8が混ざってることがあったので使い始めました。
文字コードの宣言が無いテキストを扱う場合に便利ですね。記述あっても間違ってることもありますしね。

公式サイト


使い方

使い方は簡単です。

ディテクターの作成して、
UniversalDetector detector = new UniversalDetector(null);

文字列を判別するまでストリームを読み込み
 int nread;
   while ((nread = fis.read(buf)) > 0 && !detector.isDone()) {
     detector.handleData(buf, 0, nread);
   }
detector.dataEnd();

判別結果を取得します。
detector.getDetectedCharset();

注意点は、判別できないとnullを返すところ
あとは、Windowsでよく使われるメモ帳がUTF-8で保存する再に
Byte Order Markというゴミを最初の1byteに含みます。

そのため、UTF-8を読み込む場合は、このゴミの性で、不正文字 \65279のエラーが出ることが多々あります。

自作判別読み込みライブラリー

私はファイル読み込みにしか対応していませんが、こういうライブラリーを作って使っています。

DetectUtils.java

package jp.sourceforge.akjrcp.commons.util;

/*
 * 
 * Copyright [akjava.com] [name of copyright owner]

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
 * 
 */

import java.io.File;
import java.io.IOException;

import org.apache.commons.io.FileUtils;
import org.mozilla.universalchardet.UniversalDetector;

public class DetectUtils {
public static final String ENCODING_MS932="MS932";
public static final String defaultEncoding="MS932";
public static String lastEncoding;
public static String getEncoding(File file){
try{
java.io.FileInputStream fis = new java.io.FileInputStream(file);
byte[] buf = new byte[4096];
   UniversalDetector detector = new UniversalDetector(null);

   int nread;
   while ((nread = fis.read(buf)) > 0 && !detector.isDone()) {
     detector.handleData(buf, 0, nread);
   }

   detector.dataEnd();
   return  detector.getDetectedCharset();
}catch(Exception e){
e.printStackTrace();
}

return null;
}
public static String readFileToString(File file) throws IOException{
String encode=getEncoding(file);
if(encode==null){
encode=defaultEncoding;
}
String text=FileUtils.readFileToString(file, encode);
if(text.charAt(0) == 65279){//UTF-8 marker
text=text.substring(1);
}
return text;
}
}



Comments