UTF-8の「BOM付き」と「BOMなし」はどう違う?CSVではどっちを使うべきか

CSVの文字コードを調べていると、「UTF-8(BOM付き)」と「UTF-8(BOMなし)」という表記に出くわすことがあります。同じUTF-8なのに何が違うのか、そしてCSVではどちらを使えばいいのか。この記事ではその疑問に答えます。

BOMとは何か

BOMは「Byte Order Mark」の略で、ファイルの先頭に付く3バイトのマーク(EF BB BF)です。ファイルを読むソフトウェアに対して「このファイルはUTF-8で書かれていますよ」と教える目印の役割を果たします。

テキストエディタでファイルを開いても、BOMは目に見えません。しかし、バイナリエディタで先頭3バイトを確認すると、BOM付きのファイルではEF BB BFが入っているのがわかります。

BOMあり: EF BB BF 41 42 43 ...  (先頭3バイトがBOM)
BOMなし: 41 42 43 ...            (いきなりデータ本体)

もともとBOMはUTF-16でバイト順(ビッグエンディアンかリトルエンディアンか)を判別するために設計されたものです。UTF-8にはバイト順の概念がないため、技術的にはBOMは不要です。しかし、「このファイルはUTF-8である」というヒントとして使われるようになりました。

なぜExcelにはBOMが必要なのか

ここがCSVでBOMが話題になる最大の理由です。Microsoft Excelは、CSVファイルをダブルクリックして開いたとき、BOMがなければファイルの文字コードを自動判定しようとします。そして日本語Windows環境では、BOMなしUTF-8をShift-JISだと誤判定してしまうことが非常に多いのです。

結果として、UTF-8で保存されたCSVをExcelで開くと文字化けする——という定番トラブルが発生します。

一方、BOM付きUTF-8であれば、Excelは先頭のEF BB BFを検出して「UTF-8で読めばいいんだな」と正しく判断します。だから文字化けしません。

Excel 2016以降では改善が進んでいますが、完全ではありません。確実にExcelで開かせたいCSVなら、BOM付きUTF-8がベストです。

BOM付きのデメリットはあるか

万能に見えるBOM付きUTF-8ですが、いくつかの注意点があります。

まず、一部のシステムやプログラムがBOMを「余分な文字」として認識してしまうケースがあります。たとえば、古いPHPのバージョンではBOMが原因で「ヘッダーが既に送信されています」というエラーが出ることがありました。シェルスクリプトの先頭にBOMがあると、#!/bin/bash が正しく認識されないこともあります。

また、CSVをプログラムで読み込む際に、BOMが1列目のヘッダー名に紛れ込んで「キー名が一致しない」というトラブルが起きることもあります。Pythonのcsvモジュールで読み込むと、1列目の名前が\ufeffIDのようになってしまうのです(csv.DictReader使用時)。

# PythonでBOMを処理する例
import csv

with open('data.csv', encoding='utf-8-sig') as f:  # utf-8-sig がBOMを自動除去
    reader = csv.DictReader(f)
    for row in reader:
        print(row['ID'])  # BOMが除去されるのでキー名が正しく使える

BOM付き・BOMなしの使い分け

用途おすすめ理由
Excelで開くCSVBOM付きUTF-8文字化け防止の最善策
WebサービスへのインポートどちらでもOK(大半はBOMを無視)Shopify、freeeなどは両方対応
プログラムでの読み込みBOMなし推奨BOMがヘッダー名に混入するリスク回避
Linux/Mac環境のツールBOMなし推奨BOMを認識しないツールがある
社内配布用(Excel利用者が多い)BOM付きUTF-8受け取った人が何も考えずに開ける

迷ったときの判断基準はシンプルです。「そのCSVを開く人がExcelユーザーかどうか」。YesならBOM付き、NoならBOMなしにしておけば、たいていのケースはカバーできます。

BOMの有無を確認する方法

手元にあるCSVファイルにBOMが付いているかどうかを確認するには、いくつかの方法があります。

テキストエディタを使う場合、VSCodeならステータスバーの右下に「UTF-8 with BOM」または「UTF-8」と表示されます。サクラエディタでは「文字コード」の表示で確認できます。

コマンドラインなら、fileコマンド(Mac/Linux)やPowerShellのGet-Contentで確認できます。

# Mac / Linux
file data.csv
# → data.csv: UTF-8 Unicode (with BOM) text

# PowerShell
(Get-Content data.csv -Encoding Byte)[0..2]
# → 239 187 191  (= EF BB BF)

CSV Rescueのバリデーションツールでも、BOMの有無を自動検出して報告します。ファイルをドロップするだけで確認できるので、コマンドラインに慣れていない方でも簡単です。

BOMの有無を含むCSVの構造チェックを自動実行。

CSVバリデーションツール →

BOMを付ける・外す方法

BOMの付け外しは文字コード変換で行います。Excelの「名前をつけて保存」で「CSV UTF-8(コンマ区切り)」を選択すると、BOM付きUTF-8で保存されます。一方、「CSV(コンマ区切り)」はShift-JISで保存されるので注意してください(日本語Windows環境の場合)。

プログラムでBOMを付けるのも簡単です。ファイルの先頭に\xEF\xBB\xBFを書き込めばOKです。

# PythonでBOM付きUTF-8で保存
with open('output.csv', 'w', encoding='utf-8-sig', newline='') as f:
    writer = csv.writer(f)
    writer.writerow(['ID', '名前', '金額'])
    writer.writerow(['001', '田中太郎', '10000'])

手作業なら、CSV Rescueの文字コード変換ツールで「BOM付きUTF-8」を出力先に指定するだけです。

まとめ

BOMはファイルの先頭に付く3バイトの目印で、UTF-8であることをソフトウェアに伝える役割があります。Excel環境ではBOM付きUTF-8にしておくと文字化けを防げますが、プログラムやLinux環境ではBOMが邪魔になることもあります。

最終的には「誰がそのファイルを使うのか」で判断すればOK。Excelユーザーが相手ならBOM付き、エンジニアが相手ならBOMなし、という使い分けが実用的です。

関連記事: CSVが文字化けする原因と直し方 CSVインポートエラーの対処法 ExcelでCSVが文字化けするときの対処法 改行コード(CRLF/LF)の違いと統一方法