UnicodeのBOM(バイトオーダーマーク)について

f:id:ryoutaku_jo:20190624193340p:plain

【結論】

・BOM(バイトオーダーマーク)とは、Unicodeで符号化したテキストの先頭に付与される数バイトのデータのこと

・テキストファイルを開く際に、プログラム側にUnicodeである事を認識させて、最適な設定で開かせることが出来る(ExcelなどでUTF-8のテキストを開こうとした際に、BOMが無いと文字化けする)

・Ruby2.5系では、CSV.generateでBOMが付与出来ないバグが存在する

【目次】

【本題】

BOM(バイトオーダーマーク)について

BOM(バイトオーダーマーク)とは、Unicodeで符号化したテキストの先頭に付与される数バイトのデータのことです。

これにより、テキストファイルを開く際に、プログラム側にUnicodeである事を認識させて、最適な設定で開かせることが出来ます。

例えば、Excelでテキストファイルを開くと、デフォルトではファイルをShift_JISと認識する為、UTF-8のテキストを開こうとした際に、文字化けしてしまいます。

そこでテキストファイルにBOMを付与しておけば、ファイルを開いた際に、UTF-8だと認識して最適な設定に自動で変更してくれるので、文字化けが発生しなくなります。

BOMの有無の確認方法

BOMの有無は、ターミナルで下記のコマンドを実行することで確認できます。

$ file hoge.txt

# BOMなしUTF8
hoge.txt: ASCII text 

 # BOMありUTF8
hoge.txt: UTF-8 Unicode (with BOM) text

なお、BOMの追加・削除は、下記のnkfコマンドで実行できます。

# BOMの追加
$ nkf --overwrite --oc=UTF-8-BOM hoge.txt 

# BOMの削除
$ nkf --overwrite --oc=UTF-8 hoge.txt 

nkfコマンドを利用するには、nkfを導入する必要があります。

$ brew install nkf

Ruby2.5系で発生するBOM関係のバグ

そもそも、今回BOMについて調べた理由なのですが、業務で実装したRubyで出力したCSVファイルをExcelで開くと、文字化けするという事象に遭遇したことがきっかけでした。

Rubyで出力したCSVファイルはデフォルトではUTF-8 なので、BOMを付けて対処しようとしましたが、様々なサイトを参考にしても、BOMが上手くつきませんでした・・・

そうして調べるうちに、以下の記事に辿り着き、Ruby2.5系のバグであることが判明しました。

secret-garden.hatenablog.com

Ruby2.5系では、CSV.generateで第1引数を上手く渡せないバグが存在する様で、下記の様にコードを実装しても、BOMが付かない様でした。

require "csv"

bom = "\uFEFF"
csv = CSV.generate(bom) do |row|
# 以下略

参考情報

https://wa3.i-3-i.info/word11423.html

Unicode - Wikipedia

nkf コマンド | コマンドの使い方(Linux) | hydroculのメモ

BOM(バイトオーダーマーク)とは - IT用語辞典 e-Words

【メモ】コマンドでのBOMの追加・削除・確認 - Qiita

初心者でも分かる「文字コードはとりあえずUTF-8にする」という歴史的背景 | ウェブジェネ

英語版 Office for Mac で .csv ファイルを開くと文字化けする問題 - Fascinated with Tofu

Excelで開くと文字化けするUTF-8のCSVを文字コードを変換せずに開く方法 | プライマリーテキスト

UTF-8のBOM付き・BOM無しの違いと確認方法 | UX MILK

《今日の学習進捗(3年以内に10000時間に向けて)》

先週から苦慮していた文字化けする原因がRuby2.5系のバグであることが判明した。

言語自体のバグに遭遇するのは初めてで、オープンソースは正常に動作するのが当然の様な認識を持っていた為、実装したコードばかり注視した結果、原因特定に時間を要してしまった。

頻繁に発生するケースでは無いだろうが、言語やライブラリ自体にバグが混入している可能性があることは、今後デバックを行う際に頭の片隅に置いておきたい。

また、本日のCTOとの1on1にて、インフラ関連のスキルを習得したいのであれば、もっと貪欲に現場から学んだ方が良いとアドバイス頂いた。

正直、インフラ周りの知見が全く無い事もあり、これまではインフラ関連でトラブルが発生しても、先輩頼りだったが、それではいつまで経ってもスキルが身に付かないと改めて感じた。

これからは、何かトラブルが発生したら、とりあえず首を突っ込んでいきたい。

学習開始からの期間 :199日
今日までの合計時間:1933h
一日あたりの平均学習時間:9.8h
今日までに到達すべき目標時間:1817h
目標との解離:116h
「10,000時間」まで、

残り・・・「8067時間!」