【結論】
・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系のバグであることが判明しました。
Ruby2.5系では、CSV.generateで第1引数を上手く渡せないバグが存在する様で、下記の様にコードを実装しても、BOMが付かない様でした。
require "csv" bom = "\uFEFF" csv = CSV.generate(bom) do |row| # 以下略
参考情報
https://wa3.i-3-i.info/word11423.html
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時間!」