Encodingクラス

インスタンスの生成

Encodingクラスのコンストラクタはprotectedのため、インスタンス化するときはコードページまたはコードページ名を指定してGetEncoding()を呼びます。そこで指定可能なコードページは、GetEncodings()で確認できます。Encoding.GetEncodings メソッド (System.Text) - desc | MSDN

public static Encoding GetEncoding(int codepage)
Encoding.GetEncoding メソッド (Int32) (System.Text) | MSDN
public static Encoding GetEncoding(string name)
Encoding.GetEncoding メソッド (String) (System.Text) | MSDN

なお一部のエンコーディングは、プロパティやクラスからでも取得できます。

プロパティ クラス 取得できるエンコーディング
ASCII ASCIIEncoding ASCII (7-bit)
UTF7 UTF7Encoding Unicode (UTF-7)
UTF8 UTF8Encoding BOMなしのUTF-8
Unicode UnicodeEncoding リトルエンディアンのUTF-16 (UTF-16LE)
BigEndianUnicode   ビッグエンディアンのUTF-16 (UTF-16BE)
UTF32 UTF32Encoding リトルエンディアンのUTF-32 (UTF-32LE)
プロパティ - Encoding クラス (System.Text) | MSDN

次の3つは同等のインスタンスを生成します。

Encoding enc1 = Encoding.GetEncoding(65001);   // コードページ
Encoding enc2 = Encoding.GetEncoding("utf-8"); // コードページ名
Encoding enc3 = Encoding.UTF8;                 // プロパティ

BOMありのUTF-8

BOMありのUTF-8が必要なときには、UTF8Encodingクラスのコンストラクタにtrueを渡します。

public UTF8Encoding(
    bool encoderShouldEmitUTF8Identifier
)
UTF8Encoding コンストラクター (Boolean) (System.Text) | MSDN
Encoding encoding = new UTF8Encoding(true);

プロパティ

プロパティ 内容
Encoding Default 現在のシステムのエンコーディング
プロパティ - Encoding クラス (System.Text) | MSDN

Default

システムの現在のエンコーディングが返され、それはたとえば次のようなものです。

Encoding.Default
{System.Text.DBCSCodePageEncoding}
    BodyName: "iso-2022-jp"
    CodePage: 932
    EncodingName: "日本語 (シフト JIS)"
    HeaderName: "iso-2022-jp"
    IsBrowserDisplay: true
    IsBrowserSave: true
    IsMailNewsDisplay: true
    IsMailNewsSave: true
    IsReadOnly: true
    IsSingleByte: false
    WebName: "shift_jis"
    WindowsCodePage: 932

バイト配列と文字列の変換

文字列 → バイト配列

public virtual byte[] GetBytes(
    string s
)
Encoding.GetBytes メソッド (String) (System.Text) | MSDN
byte[] bytes1 = Encoding.UTF8.GetBytes("ABC");
Console.Write(BitConverter.ToString(bytes1)); // 41-42-43

byte[] bytes2 = Encoding.UTF8.GetBytes("あい");
Console.Write(BitConverter.ToString(bytes2)); // E3-81-82-E3-81-84

バイト配列 → 文字列

[ComVisibleAttribute(false)]
public override string GetString(
    byte[] bytes,
    int index, // デコードを開始するインデックス
    int count  // デコードするバイト数
)
UTF8Encoding.GetString メソッド (Byte[], Int32, Int32) (System.Text) | MSDN
byte[] bytes1 = new byte[] { 0xE3, 0x81, 0x82, 0xE3, 0x81, 0x84 };
string str1 = Encoding.UTF8.GetString(bytes1); // "あい"

byte[] bytes2 = new byte[] { 0x41, 0x42, 0x43, 0x44 };
string str2 = Encoding.UTF8.GetString(bytes2, 1, 2); // "BC"

BOMを考慮した変換

UTF-16にはエンディアンを示すBOMが付くことがあるため、変換時にはそれを考慮する必要があります。

UTF-16LE (little-endian)

Encoding utf16le = Encoding.Unicode;

byte[] bom = utf16le.GetPreamble();    // 0xff, 0xfe
byte[] bytes = utf16le.GetBytes("あ"); // 0x42, 0x30

string a1 = utf16le.GetString(new byte[] { 0x42, 0x30 });  // "あ"
string a2 = utf16le.GetString(new byte[] { 0x30, 0x42, }); // "䈰"

string a3 = utf16le.GetString(new byte[] { 0xff, 0xfe, 0x42, 0x30 }); // "あ"
string a4 = utf16le.GetString(new byte[] { 0xfe, 0xff, 0x30, 0x42 }); // "\ufffe䈰"


int l1 = a1.Length; // 1
int l2 = a2.Length; // 1

int l3 = a3.Length; // 2 (BOMの1文字が加算される)
int l4 = a4.Length; // 2

char c1 = a1[0]; // 0x3042 'あ'
char c2 = a2[0]; // 0x4230 '䈰'
char c3 = a3[0]; // 0xfeff '' (UTF-16BEのBOM)
char c4 = a4[0]; // 0xfffe '\ufffe'

BOMがあるならば、それでエンディアンの誤りを検出して読み込み直せます。変換した文字列の最初がU+FFFE (Unknown) のときが、その場合です。

byte[] bytes = new byte[] { 0xfe, 0xff, 0x30, 0x42 };
string str = Encoding.Unicode.GetString(bytes);

if (str[0] == '\ufffe')
{
    str = Encoding.BigEndianUnicode.GetString(bytes);
}

UTF-16BE (big-endian)

Encoding utf16be = Encoding.BigEndianUnicode;
byte[] bom = utf16be.GetPreamble();    // 0xfe, 0xff
byte[] bytes = utf16be.GetBytes("あ"); // 0x30, 0x42

string a1 = utf16be.GetString(new byte[] { 0x42, 0x30 });  // "䈰"
string a2 = utf16be.GetString(new byte[] { 0x30, 0x42, }); // "あ"

string a3 = utf16be.GetString(new byte[] { 0xff, 0xfe, 0x42, 0x30 }); // "\ufffe䈰"
string a4 = utf16be.GetString(new byte[] { 0xfe, 0xff, 0x30, 0x42 }); // "あ"

UTF-8

Encoding utf8 = Encoding.UTF8;
byte[] bom = utf8.GetPreamble();    // 0xef, 0xbb, 0xbf
byte[] bytes = utf8.GetBytes("あ"); // 0xe3, 0x81, 0x82

string a1 = utf8.GetString(new byte[] { 0xe3, 0x81, 0x82 });                   // "あ"
string a2 = utf8.GetString(new byte[] { 0xef, 0xbb, 0xbf, 0xe3, 0x81, 0x82 }); // "あ"


int l1 = a1.Length; // 1
int l2 = a2.Length; // 2 (BOMの1文字が加算される)

char c1 = a1[0]; // 0x3042 'あ'
char c2 = a2[0]; // 0xfeff '' (UTF-16BEのBOM)

参考

参考書

Microsoft Learnから検索