文字コードSfift-JIS
のCSVを読み込むときに①Shift-JISに含まれていない文字、②Null、③空文字「""」といった値をキャッチする方法を記載します。
指定されたエンコーディングの例外エラーEncoderFallbackException
とは?
EncoderFallbackException
は、文字列をバイト配列に変換する際に、指定されたエンコーディング(例: Shift-JIS
)で変換できない文字が含まれていた場合に発生する例外です。
例えば、Shift-JIS
エンコーディングを使って文字列をエンコードしようとしたとき、その文字列の中に Shift-JIS
では表現できない文字(例えば、UTF-8でしか表現できない文字)を含んでいた場合、エンコーディングができないため、EncoderFallbackException
がスローされます。
✅ 具体例
-
Shift-JIS
で扱えない文字
Shift-JIS
は日本語の文字セットですが、全てのUnicode
文字をサポートしているわけではありません。
例えば、Shift-JIS
では 絵文字や一部の漢字(例えば、Unicode
の一部の新しい漢字など)はエンコードできません。
例:
文字列 "こんにちは😊" は、Shift-JISでは 😊 をエンコードできません。
string value = "こんにちは😊"; // "😊" は Shift-JIS ではエンコードできない
byte[] bytes = Encoding.GetEncoding(932).GetBytes(value); // ここでエラーが発生
✅ どうして EncoderFallbackException
が発生するのか?
エンコーディングは、文字をバイトに変換するプロセスです。例えば、UTF-8
や Shift-JIS
などのエンコーディングは、各文字に対応するバイト列(コードポイント)を持っています。
もし文字列の中に、エンコーディングがサポートしていない文字が含まれている場合、エンコーディング処理は失敗し、その結果として EncoderFallbackException
がスローされます。
前置きが長くなりましたが、コードはこちらになります。
using System;
using System.IO;
using System.Text;
class Program
{
static void Main(string[] args)
{
// ★ Shift-JISなどのコードページ対応を有効化
Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
string filePath = "C:\\Users\\XXXX\\source\\repos\\ConsoleApp\\ConsoleApp\\sample.csv";
if (!File.Exists(filePath))
{
Console.WriteLine($"エラー: ファイル '{filePath}' が見つかりません。");
Console.WriteLine("プロジェクトのルートに sample.csv を作成してください。");
return;
}
try
{
Encoding shiftJIS = Encoding.GetEncoding(932, new EncoderExceptionFallback(), new DecoderExceptionFallback());
foreach (string line in File.ReadLines(filePath))
{
string[] fields = line.Split(',');
if (fields.Length < 2)
{
Console.WriteLine("無効な行フォーマットです。スキップします。");
continue;
}
string value = fields[1].Trim('\"');
Console.WriteLine($"--- ID: {fields[0]} ---");
Console.WriteLine($"文字列: '{value}'");
try
{
//NULLもしくは空文字列の場合
if (string.IsNullOrEmpty(value) || value == "null")
{
Console.WriteLine("→ Shift-JIS変換: 失敗しました。文字列がNullもしくは空です。");
continue;
}
byte[] bytes = shiftJIS.GetBytes(value);
Console.WriteLine("→ Shift-JIS変換: 成功しました。");
}
catch (EncoderFallbackException ex)
{
Console.WriteLine($"→ Shift-JIS変換: 失敗しました(変換できない文字が含まれています)。{ex.Message}");
}
}
}
catch (Exception ex)
{
Console.WriteLine($"エラーが発生しました: {ex.Message}");
}
}
}
トラブルシューティング
「Encoding shiftJIS = Encoding.GetEncoding(932, new EncoderExceptionFallback(), new DecoderExceptionFallback());」の箇所でエラー「No data is available for encoding 932. For information on defining a custom encoding, see the documentation for the Encoding.RegisterProvider method.」になった。
発生している下記のエラー⇩
No data is available for encoding 932.
For information on defining a custom encoding, see the documentation for the Encoding.RegisterProvider method.
🔍 原因
.NET Core / .NET 5 以降の環境では、Shift-JIS などの一部の日本語コードページ(932など)がデフォルトでは利用できないようになっています。
.NET Core, .NET 5+, .NET 6, .NET 7, .NET 8 などはセキュリティ・パフォーマンス向上のため、多くの非UTFエンコーディングを無効化しています。
コードページ 932(Shift_JIS)を使用するには、エンコーディングプロバイダを登録する必要があります。
✅ 解決策:エンコーディングプロバイダを登録する
Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
修正版のコード⇩
using System;
using System.IO;
using System.Text;
class Program
{
static void Main(string[] args)
{
// ★ Shift-JISなどのコードページ対応を有効化
Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
// Shift-JIS エンコーディングを作成
Encoding shiftJIS = Encoding.GetEncoding(932, new EncoderExceptionFallback(), new DecoderExceptionFallback());
string filePath = "C:\\Users\\sample.csv";
if (!File.Exists(filePath))
{
Console.WriteLine($"エラー: ファイル '{filePath}' が見つかりません。");
Console.WriteLine("プロジェクトのルートに sample.csv を作成してください。");
return;
}
try
{
foreach (string line in File.ReadLines(filePath))
{
string[] fields = line.Split(',');
if (fields.Length < 2)
{
Console.WriteLine("無効な行フォーマットです。スキップします。");
continue;
}
string value = fields[1].Trim('\"');
Console.WriteLine($"--- ID: {fields[0]} ---");
Console.WriteLine($"文字列: '{value}'");
if (string.IsNullOrEmpty(value))
{
Console.WriteLine("→ 判定結果: 文字列は null または空です。");
}
else
{
Console.WriteLine("→ 判定結果: 文字列は有効です。");
}
try
{
byte[] bytes = shiftJIS.GetBytes(value);
Console.WriteLine("→ Shift-JIS変換: 成功しました。");
}
catch (EncoderFallbackException)
{
Console.WriteLine("→ Shift-JIS変換: 失敗しました(変換できない文字が含まれています)。");
}
Console.WriteLine();
}
}
catch (Exception ex)
{
Console.WriteLine($"エラーが発生しました: {ex.Message}");
}
}
}