Java
UTF-8

UTF-8のBOMにはまった話

More than 1 year has passed since last update.

テキストファイルを読み取りたかった

 こんなテキストファイルを読み取ろうと思いました。

Data.txt
1,あああ
2,いいい
3,ううう

 例としてこれをWindows標準のメモ帳でutf-8で保存しました。
 それをJavaのStringへと読み込んで、カンマ区切りで分けました。
 splitLine[0][0] = 1、splitLine[0][1] = あああ
 みたいにString形式で保存する形です。
 そして、このsplitLine[0][0]を数値に変換しようとしてInteger.parseInt()をしたのですが、なぜかNumberFormatExceptionが発生する。
 なんじゃこれは、間違いなくこれは数値ではないのか……と40分ぐらい悩みました。
 

UTF-8にはBOMありとBOMなしの2種類がある。

 BOM(Byte Order Mark)とは

 BOMとは、UnicodeのUTF-16など16ビット幅のエンコーディング方式において、エンディアンを指定するためにファイルの先頭に記入される16ビットの値。
 UTF-16などではビット列の並びとしてビッグエンディアンとリトルエンディアンの両方を許容しているため、誤ったエンディアンで文書を読み込むと判読できなくなってしまう。このため、ファイルの先頭のBOMを読んで、文書がどちらのエンディアンで作成されたかを判別してから本文を読み込む。
 BOMは16進数で「FEFF」という16ビットの値で、誤ったエンディアンで読み込むと、これが「FFFE」となる。BOMが「FFFE」となった場合には逆のエンディアンを使って読み込めば正しく読み込むことができる。
 BOMはエンディアンの判別だけでなく、文書がUnicodeで記述されているかどうかを判別するために用いられることもある。このため、エンディアンが関係ないUTF-8などの文書でも先頭にBOMがついている場合がある。

 つまり先頭にutf-8だぞ、と示すバイト列が入っていたわけですね。
 それを知らずに読み込んだものだから、先頭数字の1にバイト列がくっついたままなので、数値に変換できないと。
 どうもWindows付属のメモ帳では標準で追加されてしまうらしいので、別のエディタを使いましょうとのこと。
 エディタ上で確認できないだけに厄介だなと思いました……。
 こういった問題は他の文字コードでも存在するのでしょうか。気になります。