JavaでUTF-8のBOMに対処する
この記事は「 Javaでファイルオープン:文字コードや追加モードなど」の補助記事です。
JavaでBOM付きUTF-8ファイルを読む
媒体上の文字コード規格、UTF-8には、規格策定者の迷いのため
一時期、先頭に3バイトのBOMと呼ばれる、バイト並び識別マーク
を置く仕様がありました。
現在はBOMはまず使われることはありませんが、Windows付属の「メモ帳」という
簡易エディタでUTF-8ファイルをうっかり作成してしまうと、ファイル先頭に
BOMが付いてしまいます。
残念なことにJavaではBOM付きのUTF-8ファイルをまともに 読むことができません。
先頭がBOMの場合スキップする方法
対処法は色々考えられますが、ここでは、BufferedInputStreamを被せ、 先頭がBOMの場合スキップし、BOMでない場合先頭まで巻き戻す形を 示します。
import java.io.*;
public class Test1 {
/** テキストファイルを読み込み用にオープンする */
public static BufferedReader openTextFileR(
String fileName
,String charSet
)throws Exception{
return new BufferedReader(
new InputStreamReader(
skipUTF8BOM(
new FileInputStream(
new File(fileName))
,charSet)
,charSet));
}
/** UTF-8のBOMをスキップする */
public static InputStream skipUTF8BOM(
InputStream is
,String charSet
)throws Exception{
if( !charSet.toUpperCase().equals("UTF-8") ) return is;
if( !is.markSupported() ){
// マーク機能が無い場合BufferedInputStreamを被せる
is= new BufferedInputStream(is);
}
is.mark(3); // 先頭にマークを付ける
if( is.available()>=3 ){
byte b[]={0,0,0};
is.read(b,0,3);
if( b[0]!=(byte)0xEF ||
b[1]!=(byte)0xBB ||
b[2]!=(byte)0xBF ){
is.reset();// BOMでない場合は先頭まで巻き戻す
}
}
return is;
}
public static void main(String[] args_){
try{
String line;
BufferedReader br;
// BOM処理なし
br = new BufferedReader(new InputStreamReader(
new FileInputStream(
new File(args_[0]))
,"utf-8"));
while( (line=br.readLine())!=null ) System.out.println(line);
br= new BufferedReader(new InputStreamReader(
new FileInputStream(
new File(args_[1]))
,"utf-8"));
while( (line=br.readLine())!=null ) System.out.println(line);
// BOM処理あり
br= openTextFileR(args_[0],"utf-8");
while( (line=br.readLine())!=null ) System.out.println(line);
br= openTextFileR(args_[1],"utf-8");
while( (line=br.readLine())!=null ) System.out.println(line);
}
catch(Exception e){
e.printStackTrace(System.err);
}
}
}
通常文字コードを指定するファイルのオープンは次のようになります。
BufferedReader br=new BufferedReader(
new InputStreamReader(
new FileInputStream(
new File(fileName))
,charSet));
このFileInputStreamに関数skipUTF8BOM()を作用させています。
skipUTF8BOM()関数は文字コードがutf-8の場合、先頭の3バイトを読み
BOMの場合はそのまま続くデータを読むように、BOMでない場合は
先頭まで巻き戻します。
他の方法としてはBOMがある場合そのまま読み進み、ない場合はオープンしなおす といった方法も可能です。
サンプル
BOM付き、BOM無しのファイルを含むサンプルを置きました。
Test1.java : プログラム utf8_BOM.txt : BOM付きUTF-8テキストファイル utf8_noBOM.txt : BOM無しUTF-8テキストファイル build.xml : ANTビルドファイル AA10_test.bat : ANTを起動し試験を実行するバッチファイルTest1.javaは先に載せたプログラムと同じです。BOM対応無しで BOM付、BOM無しファイルを読み、次にBOM対応した形で読み込みます。
次の表示が出るはずです。
[java] ?あいうえお
[java] あいうえお
[java] あいうえお
[java] あいうえお
?はBOMのため正確に読めなかった文字を表しています。
対応ライブラリ
「Javaでファイルオープン:文字コードや追加モードなど」で紹介した
ライブラリは1.28からUTF-8のBOM対応を行っています。
利用者はBOMに関して意識する必要はありません。
例えばテキストファイルの読み込み用オープンは次のような形で行います。
BufferedReader br = hiU.openTextFileR("test.txt","utf-8");
これでUTF-8-BOMの有り無しに関わらず読み込みができます。簡単である上、視認性が極めて高いと考えています。
ライブラリ説明
ダウンロードページも含むライブラリ全体の説明は にあります。オツアンドサンズのホームページは です。
| 固定リンク

