Windowsコンソールの文字エンコーディング対応状況を検証する

3 minute read

はじめに

Windowsには複数のコンソール環境が存在し、それぞれ文字エンコーディングの扱いが異なります。特に日本語環境では、Shift_JIS(cp932)、UTF-8、UTF-16 など複数のエンコーディングが混在するため、ファイルの読み書き時に文字化けが発生するケースが少なくありません。

本記事では、以下の3つのコンソール環境について、各種文字エンコーディングのファイルを正しく読み書きできるかを検証しました。

  • コマンドプロンプト(cmd.exe)
  • Windows PowerShell 5.1
  • PowerShell 7.5.4

検証は「デフォルト設定でのファイル読み込み・リダイレクト」と「エンコーディングを明示的に指定した場合の出力」の2つの観点で行っています。

検証環境

項目 バージョン
OS Windows 11 25H2
コマンドプロンプト cmd.exe(cp932)
Windows PowerShell 5.1
PowerShell 7.5.4

テストデータ

ASCII文字・カタカナ・漢字を含む複数行の日本語テキストファイル(text1.txt)を使用しました。

TESTストリングaaa日本語国債発行
TESTストリングbbb日本語
...(以下、同様の形式で計18行)

このテストファイルを13種類の文字エンコーディングで用意し、それぞれの読み込み・出力結果を確認しています。


検証1:デフォルト設定でのファイル読み込みとリダイレクト

各コンソールのデフォルト設定で、異なるエンコーディングのテキストファイルをリダイレクトし、出力ファイルが正しく読めるかを検証しました。

検証コマンド

cmd.exe:

type text1.txt > workc.txt

Windows PowerShell 5.1 / PowerShell 7.5.4:

Get-Content -Path "text1.txt" > work.txt
Get-Content -Path "text1.txt" | Set-Content set.txt
Get-Content -Path "text1.txt" | Out-File out.txt

PowerShell では >Out-File 相当)と Set-Content で出力エンコーディングの挙動が異なるため、両方を検証しています。

結果サマリー

リダイレクトや出力結果の表示は以下の様です。

  • ✅ 可能: 日本語テキストが正常に表示される
  • ❌ 不可: 文字化け、表示エラー

cmd.exe(chcp 932)

エンコーディング 結果 備考
Shift_JIS  
UTF-8  
UTF-8(BOM付き)  
UTF-16LE  
UTF-16LE(BOM付き)  
UTF-16BE  
UTF-16BE(BOM付き)  
UTF-32LE  
UTF-32LE(BOM付き) 文字化け
UTF-32BE  
UTF-32BE(BOM付き)  
ISO-2022-JP  
EUC-JP  

cmd.exe の type コマンドとリダイレクトは、ファイルの中身をバイト列としてそのまま読み出し、そのまま書き出します。エンコーディングの解釈や変換を行わないため、ほぼすべてのエンコーディングで正常にコピーされます。

唯一 UTF-32LE(BOM付き)だけが文字化けしました。UTF-32LE の BOM は FF FE 00 00 の4バイトですが、先頭の FF FE は UTF-16LE の BOM と同一です。type コマンドが BOM を検出した際に UTF-16LE と誤認し、以降のバイト列の解釈が崩れたものと考えられます。

Windows PowerShell 5.1

エンコーディング > Set-Content Out-File
Shift_JIS
UTF-8
UTF-8(BOM付き)
UTF-16LE
UTF-16LE(BOM付き)
UTF-16BE
UTF-16BE(BOM付き)
UTF-32LE
UTF-32LE(BOM付き)
UTF-32BE
UTF-32BE(BOM付き)
ISO-2022-JP
EUC-JP

Windows PowerShell 5.1 では明確なパターンが確認できます。BOM付きファイルはすべて正常に読み込めるが、BOMなしファイルは Shift_JIS 以外すべて文字化けします。 これは PowerShell 5.1 が BOM でエンコーディングを判定し、BOM がない場合はシステムデフォルトの Shift_JIS(cp932)として扱う仕様に起因します。

ISO-2022-JP は Set-Content 経由のみ正常でした。Set-Content>Out-File と異なり、バイト列をより素直に書き出す傾向があるためです。

なお、出力エンコーディングについても注目すべき挙動があります。> および Out-File は入力のエンコーディングに関わらず常に UTF-16LE(BOM付き) で出力します。一方、Set-ContentShift_JIS で出力します。これは PowerShell 5.1 の仕様であり、出力エンコーディングを変更するには -Encoding パラメータの明示的な指定が必要です。

PowerShell 7.5.4

エンコーディング > Set-Content Out-File
Shift_JIS
UTF-8
UTF-8(BOM付き)
UTF-16LE
UTF-16LE(BOM付き)
UTF-16BE
UTF-16BE(BOM付き)
UTF-32LE
UTF-32LE(BOM付き)
UTF-32BE
UTF-32BE(BOM付き)
ISO-2022-JP
EUC-JP

PowerShell 7.5.4 では、デフォルトエンコーディングが UTF-8(BOMなし) に変更されました。そのため、5.1 とは逆に Shift_JIS が文字化けし、UTF-8(BOMなし)が正常に処理されます。

BOM付きファイルの扱いは 5.1 と同様で、BOM によるエンコーディング判定が健在です。BOMなしのファイルはデフォルトの UTF-8 として解釈されるため、UTF-8 以外のBOMなしエンコーディングは文字化けします。

また、5.1 では > / Out-FileSet-Content で出力エンコーディングが異なりましたが、7.5.4 ではすべてのコマンドで統一的に UTF-8(BOMなし) で出力されます。

ISO-2022-JP が正常に処理されるのは、Get-Content がバイト列をそのまま通過させた結果と考えられます。


検証2:エンコーディングを明示的に指定した場合の出力

各コンソールでエンコーディングを指定し、日本語テキストをファイルに出力した結果です。

cmd.exe

検証コマンドの例:

chcp 65001
echo "日本語です" > echo_utf-8.txt

cmd.exe では chcp コマンドでコードページを切り替えます。

エンコーディング chcp 結果 備考
Shift_JIS 932 デフォルト
UTF-8 65001  
UTF-16LE 1200 Invalid code page
UTF-16BE 1201 Invalid code page
UTF-32LE 12000 Invalid code page
UTF-32BE 12001 Invalid code page
ISO-2022-JP 50222  
EUC-JP 20932  

cmd.exe はシングルバイトおよびダブルバイト系のエンコーディング(Shift_JIS、UTF-8、ISO-2022-JP、EUC-JP)に対応しています。UTF-16 や UTF-32 のようなマルチバイト固定長エンコーディングはコードページとして無効であり、コンソールでは使用できません。

Windows PowerShell 5.1

検証コマンドの例:

[Console]::OutputEncoding = [System.Text.Encoding]::UTF8
[Console]::InputEncoding  = [System.Text.Encoding]::UTF8
$OutputEncoding = [System.Text.Encoding]::UTF8

"日本語です" > test_utf-8.txt
"日本語です" | Set-Content test_utf-8_set.txt

PowerShell では [Console]::OutputEncoding[Console]::InputEncoding$OutputEncoding の3つの変数でエンコーディングを設定します。出力は >Out-File 相当)と Set-Content の2種類で検証しました。

エンコーディング > Set-Content 備考
Shift_JIS  
UTF-8  
UTF-16LE  
UTF-16BE コンソールで使用不可(例外発生)
UTF-32LE コンソールで使用不可
UTF-32BE コンソールで使用不可
ISO-2022-JP  
EUC-JP コンソールで使用不可

注目すべき点として、エンコーディングを設定しても > の出力は常に UTF-16LE(BOM付き)Set-Content の出力は常に Shift_JIS になります。コンソールのエンコーディング設定はファイル出力のエンコーディングには影響しません。ファイルの出力エンコーディングを変更するには、Out-File -EncodingSet-Content -Encoding のようにコマンドレットの -Encoding パラメータを使用する必要があります。

PowerShell 7.5.4

検証コマンドは Windows PowerShell 5.1 と同様です。

エンコーディング > Set-Content 備考
Shift_JIS  
UTF-8  
UTF-16LE  
UTF-16BE コンソールで使用不可
UTF-32LE コンソールで使用不可
UTF-32BE コンソールで使用不可
ISO-2022-JP CodePagesEncodingProvider 登録
EUC-JP コンソールで使用不可

PowerShell 7.5.4 でも 5.1 と同様に UTF-16BE、UTF-32、EUC-JP はコンソールエンコーディングとして使用できません。

5.1 との大きな違いとして、>Set-Content もすべて UTF-8(BOMなし) で出力されます。5.1 と同様、コンソールのエンコーディング設定はファイル出力のエンコーディングには反映されません。

また、ISO-2022-JP を使用する場合は [System.Text.Encoding]::RegisterProvider([System.Text.CodePagesEncodingProvider]::Instance) による登録が事前に必要です。これは PowerShell 7 が .NET(Core)ベースであり、レガシーエンコーディングがデフォルトでは利用できないためです。


まとめ

デフォルト設定での読み込み

3つのコンソール環境のデフォルト設定における読み込み挙動を整理すると、以下のようになります。

条件 cmd.exe PowerShell 5.1 PowerShell 7.5.4
デフォルトエンコーディング cp932 cp932 UTF-8
BOMなし・デフォルトと一致 ✅(Shift_JIS) ✅(UTF-8)
BOMなし・デフォルトと不一致 ✅(バイトスルー)
BOM付き ✅(バイトスルー)
UTF-32LE(BOM付き) ❌(BOM誤認)

cmd.exe はエンコーディング変換を行わないバイトスルー方式のため、ほぼすべてのファイルをそのまま通過させます。PowerShell は読み込み時にエンコーディングを解釈するため、BOMなしファイルでデフォルトと異なるエンコーディングは文字化けします。

デフォルト設定での出力エンコーディング

コマンド cmd.exe PowerShell 5.1 PowerShell 7.5.4
> リダイレクト 入力と同一(バイトスルー) UTF-16LE(BOM付き) UTF-8(BOMなし)
Set-Content Shift_JIS UTF-8(BOMなし)
Out-File UTF-16LE(BOM付き) UTF-8(BOMなし)

実務上の指針

cmd.exe はエンコーディング変換を行わないため、ファイルのコピーやリダイレクトでは最も安全です。ただし UTF-32LE(BOM付き)は BOM の誤認により文字化けするので注意が必要です。

Windows PowerShell 5.1 を使用する場合、BOMなしの UTF-8 ファイルを扱うには -Encoding UTF8 を明示する必要があります。また、> の出力が UTF-16LE(BOM付き)になることを認識しておくべきです。

PowerShell 7.5.4 はデフォルトが UTF-8 に統一されており、現代の開発環境では最も扱いやすい選択です。ただし、レガシーな Shift_JIS ファイルを扱う場合は -Encoding パラメータでの明示的な指定が必要になります。

BOMなしのファイルを確実に扱うには、どのコンソール環境でも -Encoding パラメータなどでエンコーディングを明示的に指定することが推奨されます。

Updated: