UnicodeのBOM(バイトオーダーマーク)について
【結論】
・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