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系のバグであることが判明しました。

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で開くと文字化けするCSVファイルへの簡単な対応方法 | プライマリーテキスト

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