sh1’s diary

プログラミング、読んだ本、資格試験、ゲームとか私を記録するところ

.NET で文字エンコーディング shift-jis を利用する

.NET (core) で、shift-jis の文字エンコーディングを利用しようとすると正しくエンコーディングを取得することができない。これは、.NET Framework 時代と異なる動作ですね。

var sjis = Encoding.GetEncoding("Shift_JIS");

Windows 環境の古いファイルは、sjisデファクトスタンダードだったこともあって、sjis で保存されていることもしばしば。

そうしたファイルを利用するときは、sjis に対応させる必要があります。

対策

Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);

対策は .NET で、(デフォルトだと)サポートされていないエンコーディングをプロバイダーに登録する、といったことになります。で、プロバイダーのインスタンスCodePagesEncodingProvider から取得する手続きの仕組みになっているようです。

どこで実行してもよいので、アプリケーションのエントリーポイントなど最初に1度だけ実行しておけばよいと思います。

で、そもそもどうして .NET Framework でサポートされていたものがサポートされていないのかといえば、やはり windows 環境での利用を主目標にしていた .NET Framework とマルチに対応する .NET で違いがあるといえます。

このあたりは、MDB でも同じようなことがありました。

サポートしている文字エンコーディングを調べる

using System;

var condings = System.Text.Encoding.GetEncodings();
foreach (var coding in condings)
{
    Console.WriteLine(
        $"{coding.DisplayName}:{coding.CodePage} - t{coding.Name}");
}

SharpLab だとこんな感じになる。

Unicode:1200 - tutf-16
Unicode (Big-Endian):1201 - tutf-16BE
Unicode (UTF-32):12000 - tutf-32
Unicode (UTF-32 Big-Endian):12001 - tutf-32BE
US-ASCII:20127 - tus-ascii
Western European (ISO):28591 - tiso-8859-1
Unicode (UTF-8):65001 - tutf-8

余談

文字エンコーディングはややこしいなと感じることがあって、MySQL で使われている文字エンコーディングを調べると utf8mb4 っていうのが出てきたんだけど末尾の mb4 ってなんだって話になる。

  • show variables like '%char%';

調べると、MySQL 界の utf8 は1~3バイトで U+FFFF を超えるものは表現できないことがわかり mb4 をつけるとそれに対応できる(4バイトになる)。つまり、ただの utf8 は絵文字がけっこう表現できない違和感ある仕様になっています。

そもそも utf8 は1~4バイトの可変長です。

ちなみに、C#MySQL みたいに問題がないわけではない。

そんなわけで全部 utf8 なんだけど、実のところ内部的には1~3バイト仕様の utf8 がいたりする。歴史的なことを考慮しないなら、(今は)utf8 は1~4バイトであるべきで、容量対策のために utf8mb3 がオプションとして用意されている、くらいのほうが間違いがないと(今は)思ったりする。

あと shift-jis だと、そもそも今の絵文字を表現できないし、もう obsolete されつつあるんだな、と。Twitter でも絵文字を使う人がかなり増えてきたし (^ω^) も、忘れ去られた歴史になる日がくるんだろうな。

参考