dotnet coreで対応しているテキストエンコーディング

SnapCrab_Microsoft Dotnet CLI for Windows (100001306 beta) Setup_2016-2-16_21-18-22_No-00

何となくBetaが出た感じのdotnet cli 1.0.0.001306環境というか、dotnet coreの”System.Text.Encoding/4.0.11-rc2-23811″にはShift JISはありません。(Shift-JISその他を使用するには追記部を参照してください。)

検証コード:(@IT .NET Tips Encodingクラスで扱えるエンコーディング名は?[C#、VB]のまま)

using System;
using System.Text;
namespace ConsoleApplication
{
    public class Program
    {
        public static void Main(string[] args)
        {
            for (int i = 0; i < 65535; i++) {
                try {
                    Encoding enc = Encoding.GetEncoding(i);
                    Console.Write(i);
                    Console.Write(", " + enc.WebName);
                    Console.Write(", " + enc.EncodingName);
                    Console.WriteLine();
                } catch {}
            }
            Console.Read();
        }
    }
}

結果:

0, utf-8, Unicode (UTF-8)
1200, utf-16, Unicode
1201, utf-16BE, Unicode (Big-Endian)
12000, utf-32, Unicode (UTF-32)
12001, utf-32BE, Unicode (UTF-32 Big-Endian)
20127, us-ascii, US-ASCII
28591, iso-8859-1, Western European (ISO)
65000, utf-7, Unicode (UTF-7)
65001, utf-8, Unicode (UTF-8)

なんと0番がUTF-8で、SJISがありませんねぇ。なので、Windowsのコンソールで日本語出力しようとするとそのままでは盛大に文字化けします。ま、LinuxとかMacならあんまり問題にならないかもね。

Windows 10(Ja-Jp)の標準コンソールで日本語を表示させようとした結果:

コード:

using System;
using System.Text;
namespace ConsoleApplication
{
    public class Program
    {
        public static void Main(string[] args)
        {
            //Console.OutputEncoding = new UTF8Encoding();
            // OutputEncodingプロパティが無い。
            var co = Console.Out;
            // Counsoleのデフォルトエンコーディングを表示
            Console.WriteLine(co.Encoding.EncodingName);            
            Console.WriteLine("Hello World!");
            Console.WriteLine("こんにちは世界");
            
            Console.Read();
        }
    }
}

実行結果:

Unicode (UTF-8)
Hello World!
縺薙s縺ォ縺。縺ッ荳也阜

といことで、注意しましょう。

追記(23:27)

藤原さんにヒントもらったので試してみました。

次のようにproject.jsonのdependenciesに"System.Text.Encoding.CodePages": "4.0.1-rc2-23811を追加します。

{
    "version": "1.0.0-*",
    "compilationOptions": {
        "emitEntryPoint": true
    },

    "dependencies": {
        "NETStandard.Library": "1.0.0-rc2-23811",
        "System.Text.Encoding.CodePages": "4.0.1-rc2-23811",
        "System.Globalization": "4.0.11-rc2-23811"
        
    },

    "frameworks": {
        "dnxcore50": { }
    }
}

コードを次のようにEncoding.RegisterProvider(CodePagesEncodingProvider.Instance);を追加します。

using System;
using System.Text;
//using System.Globalization;

namespace ConsoleApplication
{
    public class Program
    {
        public static void Main(string[] args)
        {
            Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
            for (int i = 0; i < 65535; i++) {
                try {
                    Encoding enc = Encoding.GetEncoding(i);
                    Console.Write(i);
                    Console.Write(", " + enc.WebName);
                    Console.Write(", " + enc.EncodingName);
                    Console.WriteLine();
                } catch {}
            }
            Console.Read();
        }
    }
}

実行結果:

0, shift_jis, Japanese (Shift-JIS)
...
932, shift_jis, Japanese (Shift-JIS)
...
51932, euc-jp, Japanese (EUC)
...
65000, utf-7, Unicode (UTF-7)
65001, utf-8, Unicode (UTF-8)

という事で、SJIS他のエンコーディングも使用できるようになりました。デフォルトのエンコーディングがShift_JISになっています。

ただ、Console.WriteLine("こんにちは世界");とした時の文字化けは以下のように表示されて治らないので、別の方法が必要かも。

・ス・ス・ス・スノゑソス・スヘ撰ソス・スE

追記(2016/02/21):

dotnert run とした場合には上のように文字化けしますが、.EXEを直接実行すると文字化けしないことがわかりました。実際にコンパイルしたバイナリは問題無さそう。dotnetコマンドの問題か仕様のようです。お騒がせしました。

> hwapp.exe
Japanese (Shift-JIS)
Hello World!
こんにちは世界