WebSurfer's Home

Filter by APML

.NET アプリで Shift_JIS を使うには?

by WebSurfer 14. March 2025 13:57

.NET アプリにおいて Encoding.GetEncoding メソッドで Shift_JIS のエンコーディングを取得しようとすると、以下の画像のように ArgumentException 例外がスローされます。

Shift_JIS エンコーディングの取得

これは、.NET では特定の OS に依存する機能はサポートされてないので、Shift_JIS に限らず Windows OS のコードページの中の特定の locale のエンコーディングはデフォルトでは使えないということのようです。(注: .NET Framework ではデフォルトで Windows コードページの大多数のエンコーディングが使えます)

サポートされているエンコーディングは Encoding.GetEncodings メソッドで取得できます。.NET 8.0 の場合、自分の環境で試すと以下の 7 種類になっていました。

  • ASCII (code page 20127)
  • UTF-8 (code page 65001)
  • UTF-16LE (code page 1200)
  • UTF-16BE (code page 1201)
  • UTF-32LE (code page 12000)
  • UTF-32BE (code page 12001)
  • ISO-8859-1 (code page 28591)

UTF-7 も含まれるというMicrosoft のドキュメントを目にしましたが "The UTF-7 encoding is insecure and should not be used." ということで除外されたようです。

では、.NET アプリで上の一覧にないエンコーディングを Encoding.GetEncoding メソッドで取得して使うにはどうするかですが、それについては Microsoft のドキュメント「EncodingProvider クラス」に説明があります。それを参考に以下に Shift_JIS を使う場合の例を書きます。

(1) プロバイダクラスを定義

抽象クラス EncodingProvider を継承したプロバイダクラスを定義します。この例では、プロバイダクラスの名前を ShiftJisEncodingProvider とします。

ShiftJisEncodingProvider クラスで、 継承した抽象クラス EncodingProvider の抽象メソッド GetEncoding(Int32) と GetEncoding(String) を override し、Shift_JIS エンコーディングを返すようにします。

Shift_JIS エンコーディングは CodePagesEncodingProvider クラスのインスタンスから取得します。

ShiftJisEncodingProvider クラスのコード例は以下の通りです。

using System.Text;

public class ShiftJisEncodingProvider : EncodingProvider
{
    public override Encoding? GetEncoding(int codepage)
    {
        var provider = CodePagesEncodingProvider.Instance;
        if (codepage == 932)
        {            
            return provider.GetEncoding(932);
        }

        return null;
    }

    public override Encoding? GetEncoding(string name)
    {
        var provider = CodePagesEncodingProvider.Instance;
        if (name.Equals("shift_jis", StringComparison.CurrentCultureIgnoreCase))
        {                
            return provider.GetEncoding("shift_jis");
        }
        
        return null;
    }
}

(2) ShiftJisEncodingProvider の登録

ShiftJisEncodingProvider のインスタンスを Encoding.RegisterProvider メソッド に渡して、.NET アプリで Shift_JIS エンコーディングを取得できるようにします。

(3) Shift_JIS エンコーディングの取得

.NET アプリでは Encoding.GetEncoding メソッドを使って Shift_JIS エンコーディングを取得します。ステップ (2) と (3) のコード例は以下の通りです。コメントの結果に示すように期待通り Shift_JIS エンコーディングが取得できています。

using System.Text;

namespace ConsoleApp4
{
    internal class Program
    {
        static void Main(string[] args)
        {
            var provider = new ShiftJisEncodingProvider();
            Encoding.RegisterProvider(provider);

            var sjis = Encoding.GetEncoding("shift_jis");
            Console.WriteLine($"{sjis.EncodingName}\t{sjis.CodePage}\t{sjis.WebName}");

            var str = "123abcあいう";
            Console.Write($"{str}: ");

            byte[] bytes = sjis.GetBytes(str);
            foreach (byte b in bytes)
            {
                Console.Write($"[{b:x2}]");
            }            
        }
    }
}

// 結果:
// Japanese (Shift-JIS)    932     shift_jis
// 123abcあいう: [31][32][33][61][62][63][82][a0][82][a2][82][a4]

上で述べたようなカスタムプロバイダクラスを定義しなくても Windows コードページのエンコーディングを簡単に全部使えるようにする方法もあります。

その方法は、Microsoft のドキュメント「CodePagesEncodingProvider クラス」に説明があります。

  1. CodePagesEncodingProvider.Instance 静的プロパティから CodePagesEncodingProvider オブジェクトを取得します。
  2. CodePagesEncodingProvider オブジェクトを Encoding.RegisterProvider メソッドに渡します。

コード例は以下の通りで一行で済みます。必要ないエンコーディングまで使えるようにすることで何か予期せぬ副作用が出るかもしれないという可能性は否定しきれませんが、こちらのが本筋かもしれません。

using System.Text;

namespace ConsoleApp4
{
    internal class Program
    {
        static void Main(string[] args)
        {
            // 以下の一行で OK
            Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);

            var sjis2 = Encoding.GetEncoding("shift_jis");
            Console.WriteLine($"{sjis2.EncodingName}\t{sjis2.CodePage}\t{sjis2.WebName}");

            Console.Write($"{str}: ");

            byte[] bytes2 = sjis2.GetBytes(str);
            foreach (byte b in bytes2)
            {
                Console.Write($"[{b:x2}]");
            }

            Console.WriteLine("\n\nサポートしているすべてのエンコーディングを取得する");
            EncodingInfo[] eis = Encoding.GetEncodings();
            foreach (EncodingInfo ei in eis)
            {
                Console.WriteLine($"{ei.DisplayName}\t{ei.CodePage}\t{ei.Name}");
            }
        }
    }
}

/* 結果
Japanese (Shift-JIS)    932     shift_jis
123abcあいう: [31][32][33][61][62][63][82][a0][82][a2][82][a4]

サポートしているすべてのエンコーディングを取得する
Japanese (Shift-JIS)    932     shift_jis
Portuguese (DOS)        860     IBM860
Icelandic (DOS) 861     ibm861
IBM EBCDIC (Cyrillic Russian)   20880   IBM880
Hebrew (DOS)    862     DOS-862
French Canadian (DOS)   863     IBM863
Chinese Simplified (GB2312)     936     gb2312
Arabic (864)    864     IBM864
Nordic (DOS)    865     IBM865
Cyrillic (DOS)  866     cp866
Cyrillic (KOI8-U)       21866   koi8-u
IBM EBCDIC (US-Canada)  37      IBM037
Greek, Modern (DOS)     869     ibm869
IBM EBCDIC (International)      500     IBM500
Icelandic (Mac) 10079   x-mac-icelandic
IBM EBCDIC (US-Canada-Euro)     1140    IBM01140
IBM EBCDIC (Germany-Euro)       1141    IBM01141
IBM EBCDIC (Denmark-Norway-Euro)        1142    IBM01142
IBM EBCDIC (Germany)    20273   IBM273
IBM EBCDIC (Finland-Sweden-Euro)        1143    IBM01143
IBM EBCDIC (Italy-Euro) 1144    IBM01144
IBM EBCDIC (Spain-Euro) 1145    IBM01145
Central European (Windows)      1250    windows-1250
IBM EBCDIC (UK-Euro)    1146    IBM01146
Cyrillic (Windows)      1251    windows-1251
IBM EBCDIC (France-Euro)        1147    IBM01147
Western European (Mac)  10000   macintosh
Western European (Windows)      1252    windows-1252
Arabic (DOS)    720     DOS-720
IBM EBCDIC (Denmark-Norway)     20277   IBM277
IBM EBCDIC (International-Euro) 1148    IBM01148
Japanese (Mac)  10001   x-mac-japanese
Greek (Windows) 1253    windows-1253
OEM United States       437     IBM437
IBM EBCDIC (Finland-Sweden)     20278   IBM278
IBM EBCDIC (Icelandic-Euro)     1149    IBM01149
Chinese Traditional (Mac)       10002   x-mac-chinesetrad
Turkish (Windows)       1254    windows-1254
Hebrew (Windows)        1255    windows-1255
Korean (Johab)  1361    Johab
Arabic (Windows)        1256    windows-1256
Arabic (Mac)    10004   x-mac-arabic
Baltic (Windows)        1257    windows-1257
Hebrew (Mac)    10005   x-mac-hebrew
Vietnamese (Windows)    1258    windows-1258
Greek (Mac)     10006   x-mac-greek
Cyrillic (Mac)  10007   x-mac-cyrillic
IBM Latin-1     20924   IBM00924
Central European (ISO)  28592   iso-8859-2
Latin 3 (ISO)   28593   iso-8859-3
Baltic (ISO)    28594   iso-8859-4
Cyrillic (ISO)  28595   iso-8859-5
Arabic (ISO)    28596   iso-8859-6
IBM EBCDIC (Multilingual Latin-2)       870     IBM870
Greek (ISO)     28597   iso-8859-7
Hebrew (ISO-Visual)     28598   iso-8859-8
Turkish (ISO)   28599   iso-8859-9
Turkish (Mac)   10081   x-mac-turkish
Croatian (Mac)  10082   x-mac-croatian
Thai (Windows)  874     windows-874
IBM EBCDIC (Greek Modern)       875     cp875
IBM EBCDIC (Arabic)     20420   IBM420
Korean  949     ks_c_5601-1987
IBM EBCDIC (Greek)      20423   IBM423
IBM EBCDIC (Hebrew)     20424   IBM424
IBM EBCDIC (Italy)      20280   IBM280
IBM Latin-1     1047    IBM01047
IBM EBCDIC (Spain)      20284   IBM284
IBM EBCDIC (UK) 20285   IBM285
Romanian (Mac)  10010   x-mac-romanian
Japanese (JIS 0208-1990 and 0212-1990)  20932   EUC-JP
Ukrainian (Mac) 10017   x-mac-ukrainian
Europa  29001   x-Europa
Greek (DOS)     737     ibm737
Western European (IA5)  20105   x-IA5
Chinese Traditional (Big5)      950     big5
Chinese Simplified (GB2312-80)  20936   x-cp20936
German (IA5)    20106   x-IA5-German
Swedish (IA5)   20107   x-IA5-Swedish
Norwegian (IA5) 20108   x-IA5-Norwegian
Cyrillic (KOI8-R)       20866   koi8-r
Baltic (DOS)    775     ibm775
Estonian (ISO)  28603   iso-8859-13
IBM EBCDIC (Japanese katakana)  20290   IBM290
Latin 9 (ISO)   28605   iso-8859-15
Chinese Traditional (CNS)       20000   x-Chinese-CNS
Arabic (ASMO 708)       708     ASMO-708
IBM EBCDIC (France)     20297   IBM297
Thai (Mac)      10021   x-mac-thai
TCA Taiwan      20001   x-cp20001
IBM EBCDIC (Turkish)    20905   IBM905
Chinese Traditional (Eten)      20002   x-Chinese-Eten
IBM EBCDIC (Korean Extended)    20833   x-ebcdic-koreanextended
IBM5550 Taiwan  20003   x-cp20003
TeleText Taiwan 20004   x-cp20004
Wang Taiwan     20005   x-cp20005
Western European (DOS)  850     ibm850
IBM EBCDIC (Thai)       20838   IBM-Thai
Central European (DOS)  852     ibm852
IBM EBCDIC (Icelandic)  20871   IBM871
Central European (Mac)  10029   x-mac-ce
OEM Cyrillic    855     IBM855
IBM EBCDIC (Cyrillic Serbian-Bulgarian) 21025   cp1025
Korean Wansung  20949   x-cp20949
Turkish (DOS)   857     ibm857
OEM Multilingual Latin I        858     IBM00858
T.61    20261   x-cp20261
IBM EBCDIC (Turkish Latin-5)    1026    IBM1026
ISO-6937        20269   x-cp20269
Unicode 1200    utf-16
Unicode (Big-Endian)    1201    utf-16BE
Unicode (UTF-32)        12000   utf-32
Unicode (UTF-32 Big-Endian)     12001   utf-32BE
US-ASCII        20127   us-ascii
Western European (ISO)  28591   iso-8859-1
Unicode (UTF-8) 65001   utf-8
*/

Tags: , , ,

CORE

About this blog

2010年5月にこのブログを立ち上げました。主に ASP.NET Web アプリ関係の記事です。ブログ2はそれ以外の日々の出来事などのトピックスになっています。

Calendar

<<  June 2025  >>
MoTuWeThFrSaSu
2627282930311
2345678
9101112131415
16171819202122
23242526272829
30123456

View posts in large calendar