Encodingクラスのプロパティやメソッドを使って、各種のエンコーディング(特に日本語のエンコーディング)に対応したインスタンスを得る方法を説明する。
本稿は2003/04/11に初版公開、2008/07/24に改訂した記事を再改訂し、Visual Studio 2017でコードの動作検証、図版の追加、全般的な構成の変更などを行ったものです。
ファイルの読み書きなどで文字コードを指定したいときがある。そのために使うEncodingクラス(System.Text名前空間)のインスタンスは、どのようにして取得すればよいだろうか? また、日本語独自のエンコーディングを指定するには、どのようなエンコーディング名が使えるのだろうか? 本稿で整理して紹介する。
特定のトピックをすぐに知りたいという方は以下のリンクを活用してほしい。
一般的なエンコーディングは、Encodingクラスの静的プロパティとして提供されている(次のコード)。新しく構築するシステムなら、その中からUnicode(UTF-8やUTF-16)を使っておけばよい。
// UTF-8
var utf8 = System.Text.Encoding.UTF8;
System.Console.WriteLine(utf8.EncodingName);
// 出力:Unicode (UTF-8)
// UTF-16(リトルエンディアン)
var utf16 = System.Text.Encoding.Unicode;
System.Console.WriteLine(utf16.EncodingName);
// 出力:Unicode
// ASCII(7ビット)
var ascii = System.Text.Encoding.ASCII;
System.Console.WriteLine(ascii.EncodingName);
// 出力:US-ASCII
' UTF-8
Dim utf8 = System.Text.Encoding.UTF8
System.Console.WriteLine(utf8.EncodingName)
' 出力:Unicode (UTF-8)
' UTF-16(リトルエンディアン)
Dim utf16 = System.Text.Encoding.Unicode
System.Console.WriteLine(utf16.EncodingName)
' 出力:Unicode
' ASCII(7ビット)
Dim ascii = System.Text.Encoding.ASCII
System.Console.WriteLine(ascii.EncodingName)
' 出力:US-ASCII
既存のシステムやデータの場合、Unicodeではなく日本語独自のエンコーディングを使っている場合がある。そのようなエンコーディングは上記の静的プロパティでは得られない。
「TIPS:文字列をシフトJISとしてバイト列に変換するには?」や「TIPS:バイト列を文字列に変換するには?」では、文字列のエンコーディングとしてシフトJISを使用するために、シフトJISをサポートしているEncodingクラス(System.Text名前空間)のインスタンスを次のようにして取得している*1。
Encoding sjisEnc = Encoding.GetEncoding("Shift_JIS");
Dim sjisEnc As Encoding = Encoding.GetEncoding("Shift_JIS")
ここではパラメーターとして、シフトJISの文字コード体系(キャラクタセット)を表す値を文字列「Shift_JIS」で指定している。シフトJIS以外では、日本語のエンコーディングによく使用されるキャラクタセットとして、次のようなものが指定できる。
GetEncodingメソッドのパラメーターには、キャラクタセットの名前ではなく、それに対応したコードページの値を指定することもできる。例えば、シフトJISに対応したコードページ値は932なので、上のコードは次のように記述しても同等だ。
Encoding sjisEnc = Encoding.GetEncoding(932);
Dim sjisEnc As Encoding = Encoding.GetEncoding(932)
ちなみに、Encodingクラスは既定のインスタンスも提供している(次のコード)。これは、システムのデフォルトのエンコーディングであり、日本語環境ではシフトJISになっている。システムの設定言語が異なればこのエンコーディングも変わってくるので、シフトJISのエンコーディングが欲しいというときにこれを使ってはいけない。
Encoding defaultEnc = Encoding.Default;
Console.WriteLine("{0}, {1}, {2}", defaultEnc.CodePage,
defaultEnc.WebName, defaultEnc.EncodingName);
// 出力:932, shift_jis, 日本語 (シフト JIS)
Dim defaultEnc As Encoding = Encoding.Default
Console.WriteLine("{0}, {1}, {2}", defaultEnc.CodePage,
defaultEnc.WebName, defaultEnc.EncodingName)
' 出力:932, shift_jis, 日本語 (シフト JIS)
*1 .NET Core 1.xでは、EncodingクラスのGetEncodingメソッドを呼び出す前に一度だけRegisterProviderメソッドを呼び出しておく必要がある(.NET Core 2.0以降と.NET Frameworkでは不要)。
詳しくは「WinRT/Metro TIPS:シフトJISのEncodingオブジェクトを取得するには?[Windows 10 UWPアプリ開発]」をご覧いただきたい。
docs.microsoft.comのEncodingクラスのページには、GetEncodingメソッドに渡せるエンコーディング名とコードページ番号の一覧が載っている。しかし、そのページの情報が正しいとは限らない(実際、本稿執筆時点の日本語版では、エンコーディング名の一部が日本語に翻訳されてしまっていて、正しい名前ではなかった)。
プログラムでエンコーディングの一覧を取得するには、.NET Framework 2.0以降ではEncodingクラスのGetEncodingsメソッドが使える(次のコード)。このメソッドは、EncodingInfoクラスの配列を返してくる。EncodingInfoクラスは、エンコーディング名とコードページのプロパティを持っている。なお、EncodingInfoクラスのGetEncodingメソッドで、そのエンコーディングのEncodingインスタンスが得られる。
using System;
using System.Linq;
using System.Text;
class Program
{
static void Main(string[] args)
{
// 全てのエンコーディング情報を取得
EncodingInfo[] allEncodings = Encoding.GetEncodings();
Console.WriteLine("エンコーディング数={0}", allEncodings.Length);
// 出力:エンコーディング数=140
// 表示名に「日本語」を含むエンコーディング
var japaneseEI = allEncodings.Where(ei => ei.DisplayName.Contains("日本語"));
Console.WriteLine("CodePage\tName\tDisplayName");
foreach (EncodingInfo ei in japaneseEI)
Console.WriteLine("{0}\t{1}\t{2}", ei.CodePage, ei.Name, ei.DisplayName);
// 出力:
// CodePage Name DisplayName
// 932 shift_jis 日本語 (シフト JIS)
// 10001 x-mac-japanese 日本語 (Mac)
// 20290 IBM290 IBM EBCDIC (日本語カタカナ)
// 20932 EUC-JP 日本語 (JIS 0208-1990 および 0212-1990)
// 50220 iso-2022-jp 日本語 (JIS)
// 50221 csISO2022JP 日本語 (JIS 1 バイト カタカナ可)
// 50222 iso-2022-jp 日本語 (JIS 1 バイト カタカナ可 - SO/SI)
// 51932 euc-jp 日本語 (EUC)
// 同名のものを指定してEncodingインスタンスを取得すると?
Console.WriteLine(Encoding.GetEncoding("iso-2022-jp").CodePage);
// 出力:50220
Console.WriteLine(Encoding.GetEncoding("EUC-JP").CodePage);
// 出力:51932
Console.WriteLine(Encoding.GetEncoding("euc-jp").CodePage);
// 出力:51932
#if DEBUG
Console.ReadKey();
#endif
}
}
Imports System.Text
Module Module1
Sub Main()
' 全てのエンコーディング情報を取得
Dim allEncodings As EncodingInfo() = Encoding.GetEncodings()
Console.WriteLine("エンコーディング数={0}", allEncodings.Length)
' 出力:エンコーディング数=140
' 表示名に「日本語」を含むエンコーディング
Dim japaneseEI _
= allEncodings.Where(Function(ei) ei.DisplayName.Contains("日本語"))
Console.WriteLine("CodePage" + vbTab + "Name" + vbTab + "DisplayName")
For Each ei As EncodingInfo In japaneseEI
Console.WriteLine("{0}{1}{2}{3}{4}",
ei.CodePage, vbTab, ei.Name, vbTab, ei.DisplayName)
Next
' 出力:
' CodePage Name DisplayName
' 932 shift_jis 日本語 (シフト JIS)
' 10001 x-mac-japanese 日本語 (Mac)
' 20290 IBM290 IBM EBCDIC (日本語カタカナ)
' 20932 EUC-JP 日本語 (JIS 0208-1990 および 0212-1990)
' 50220 iso-2022-jp 日本語 (JIS)
' 50221 csISO2022JP 日本語 (JIS 1 バイト カタカナ可)
' 50222 iso-2022-jp 日本語 (JIS 1 バイト カタカナ可 - SO/SI)
' 51932 euc-jp 日本語 (EUC)
' 同名のものを指定してEncodingインスタンスを取得すると?
Console.WriteLine(Encoding.GetEncoding("iso-2022-jp").CodePage)
' 出力:50220
Console.WriteLine(Encoding.GetEncoding("EUC-JP").CodePage)
' 出力:51932
Console.WriteLine(Encoding.GetEncoding("euc-jp").CodePage)
' 出力:51932
#If DEBUG Then
Console.ReadKey()
#End If
End Sub
End Module
上のサンプルコードでは、日本語用のエンコーディングを抜き出して表示している。全てのエンコーディングを出力する例は、docs.microsoft.comのEncodingInfo.GetEncodingのページに載っている。
実際には、GetEncodingメソッドのパラメーターで指定可能な文字列の元となるデータは、レジストリの次のキー配下で定義されているようだ。
HKEY_CLASSES_ROOT\MIME\Database\Charset
ここでは、キャラクタセット名に加えて、その別名(Alias)も定義されている。例えば、「Shift_JIS」の別名としては、次のようなものがある。
これらの文字列はどれも、「Shift_JIS」の代わりにGetEncodingメソッドのパラメーターとして使用できる。
カテゴリ:クラスライブラリ 処理対象:文字列
使用ライブラリ:Encodingクラス(System.Text名前空間)
使用ライブラリ:EncodingInfoクラス(System.Text名前空間)
関連TIPS:文字列の長さを取得するには?
関連TIPS:文字列をシフトJISとしてバイト列に変換するには?
関連TIPS:バイト列を文字列に変換するには?
関連TIPS:Visual Studioでコンソール・アプリケーションのデバッグ実行時にコマンド・プロンプトを閉じないようにするには?
【2018/10/10】Visual Studio 2017でコードの動作検証、図版の追加、全般的な構成の変更などを行いました。
【2008/07/24】VB(Visual Basic)のコード例とサンプルプログラムを追加しました。
【2003/04/11】初版公開。
Copyright© Digital Advantage Corp. All Rights Reserved.