WebSurfer's Home

トップ > Blog 1   |   ログイン
APMLフィルター

BOM 無し UTF-8 と StreamReader

by WebSurfer 2020年5月20日 14:36

Windows 10 のあるバージョンから、メモ帳でテキストを保存する際の文字コードのデフォルトが ANSI から UTF-8 に変わりました。下の画像を見てください。

メモ帳の文字コード

上の画像で、[ANSI] は「BOM なし Shift_JIS」、[UTF-8] は「BOM なし UTF-8」となります。それ以外はすべて BOM つきとなります。

その変更で気になっていたのは、以前のメモ帳のデフォルト [ANSI] 即ち「BOM なし Shift_JIS」を期待して StreamReader コンストラクタの Encoding を Shift_JIS に指定した以下のようなコードを使っている場合、新しいメモ帳のデフォルト「BOM なし UTF-8」で保存されたファイルを読むとどうなるかということです。

using (StreamReader reader = new StreamReader(
                             dir + "UTF8withoutBOM.txt", 
                             Encoding.GetEncoding("Shift_JIS")))
{
    Console.WriteLine(reader.ReadToEnd());
}

ダメだろうとは思いながらも、念のため試してみましたがやっぱり当たり前にダメでした。下の画像の一行目がそれで、文字化けしています。

結果

上の画像の二行目以降は、順に、メモ帳で保存するとき [UTF-8 (BOM つき)]、[ANSI]、[UTF-16 BE]、[UTF-16 LE] を選んだものです。

[UTF-8] は「BOM なし UTF-8」で、BOM が付いてないので StreamReader コンストラクタの第 2 引数に指定された Shift_JIS としてデコードされ、その結果文字化けしています。

[ANSI] は「BOM なし Shift_JIS」で、これも BOM なしですが、StreamReader コンストラクタの第 2 引数で正しく指定されている通り Shift_JIS としてデコードするので問題なしです。

[UTF-8] と [ANSI] 以外は有効な BOM が付いており、StreamReader は BOM で正しく文字コードが判定できますので、判定した通りデコードされて問題なしという結果になっています。

StreamReader コンストラクターの詳しい説明は左のリンクをクリックして Microsoft のドキュメントを見てください。

少し説明しておくと、StreamReader コンストラクタ (String, Encoding) のように Encoding を引数に指定するオーバーロードでは、ファイルの最初の 4 バイトを見てエンコーディングの検出を試み、適切な BOM で始まる場合、それによって UTF-8、リトルエンディアン Unicode、ビッグエンディアン Unicode、リトルエンディアン UTF-32、およびビッグエンディアン UTF-32 を自動的に判別し、それ以外の場合は Encoding に指定されたエンコードが使用されるそうです。

ちなみに BOM は 16 進数表現で以下の通りとなります。

  • UTF-8:    EF BB BF
  • UTF-16BE: FE FF
  • UTF-16LE: FF FE
  • UTF-32BE: 00 00 FE FF
  • UTF-32LE: FF FE 00 00

メモ帳のデフォルトが「BOM なし Shift_JIS」だった時代は、メモ帳で作るテキストファイルを読む場合、StreamReader コンストラクタの Encoding に Shift_JIS 指定を指定しておけば文字化けに悩まずに済みました。デフォルトが「BOM なし UTF-8」に変わった今はそうはいかないようです。

Tags: , ,

.NET Framework

About this blog

2010年5月にこのブログを立ち上げました。主に ASP.NET Web アプリ関係の記事です。

Calendar

<<  2024年3月  >>
252627282912
3456789
10111213141516
17181920212223
24252627282930
31123456

View posts in large calendar