Hatena::ブログ(Diary)

Kazzzの日記 このページをアンテナに追加 RSSフィード

2005-06-14 梅雨とは思えないさわやかな風がありがたいす

[][]文字エンコーディング名の狭間


仕事Javaと.NETを行ったり来たりするライブラリィを書いていますがその間を行き来するデータの殆どはHTTPプロトコルを使用したRESTXML(XML over HTTP)でやり取りするように実装しています。例えばJavaと.NETでデータ交換を目的として以下のXMLをJava側で生成したとします。

<?xml version="1.0" encoding="Windows-31J"?>
<foo>
<foobar>ふーばー</foobar>
</foo>

また、以下の様なコードでJava側から出力されたレスポンスストリームも同様のエンコーディングのはずです。

response.setContentType("text/html;charset=Windows-31J");

エンコーディング名"Windows-31J"はJ2SE1.4.1から導入されたMS932の新たなエイリアスでありWindows系のプラットホームではコンバータに問題のあるShift_JISでは無くこちらを使うのが推奨されています。※
これで.NET側でも普通に解釈できるだろうと思い.NET側でこのXMLをストリームとして読込む際にエンコーダインスタンスをEncondingクラスから取得しようとすると「そんなエンコーディング名知らんわ」と怒られてしまいます。"Windows-31J"は正式なIANA登録名だから.NETでもサポートされているんじゃないの? と以下のようなコードを書いて調べると
class EnumEncoding 
{
    public static void Main() 
    {
        //全て列挙してみる
        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
            {}
        }
    }
}

なんと.NETのEncodingクラスには名前"Windows-31J"はどこにも登録されていないのです。
ではシステムのサポートキャラクタセットとしてレジストリのMIMEにも"Windows-31J"は存在しないのかと思い自分の環境(WindowsXP/Pro)のレジストリHKEY_CLASSES_ROOT\\MIME\\Database\\Charset配下を探してみるとやはり見つかりません。がしかし代わりに使えそうな"csWindows31J"という名前がありました。これはIANAでは"Windows-31J"のエイリアスとして登録されている名前なのでXML宣言"encoding="csWindows31J""と書けば"Windows-31J"と同じになるのでこれで解決かと思ったのですが.....
このエンコーディング名"csWindows31J"ですがWindowsXPのレジストリ上では"Shift_JIS"のエイリアスとして登録されているのです。
f:id:Kazzz:20050614101724:image


まとめ

1..NETでIANA登録名である"Windows-31J"が何故かサポートされていない
2.本来"Windows-31J"の別名である"csWindows31j"が何故か"Shift_JIS"の別名である

従って現状、Javaと.NET間で日本語を含むXMLやHTMLを正しく交換したりプラットホーム間で申し合わせてストリームをやり取りする為にエンコーディングを合わせようとするとJava側で最もポピュラーと思われる"Windows-31J"は使用できません。結局はプラットホームを限定しないケースでは事実utf-8しか選択肢がありません。(Shift_JISは特定のUNICODE文字やDBMS等で問題が出る事が避けられないので使わないほうが良いです)

少し前にSunとMSとの和解及び戦略的な連携がニュースになりましたが連携言うならまずはこの辺から合わせて欲しいものです。

追記:※Javaの日本語エンコーディングのエイリアスの経緯に関しては風間氏のno titleがとても参考になります。


追記:エンコーディングの列挙のコードですが.NET2.0から列挙用のメソッドが追加されたのでもっとすっきりと書けますし重複も無く速度も段違いに速いです。

//for.NET2.0 beta2
class EnumEncoding
{
    public static void Main()
    {
        foreach (EncodingInfo info in Encoding.GetEncodings() )
        {
            Console.Write(info.CodePage);
            Console.Write(", " + info.Name);
            Console.Write(", " + info.DisplayName);
            Console.WriteLine();
        }
    }
}

中博俊中博俊 2005/06/14 10:17 問い合わせてみるとしましょう

中博俊中博俊 2005/06/14 10:33 >少し前にSunとMSとの和解及び戦略的な連携がニュースになりましたが連携言うならまずはこの辺から合わせて欲しいものです。
とはいえこれは大仰に過ぎるかな。
Windowsの問題ですしねそう簡単に対応は難しいでしょう。Longhorn期待

kazuyakazuya 2005/06/14 12:54 エンコーディングには弱いのですが
Encoding encoding = Encoding.GetEncoding(932);
でもやはり、Shift_JISになってしまうのでしょうか?
確かにクラスライブラリの説明には
日本の shift-jis コード ページ (コード ページ 932)
となってますね。

KazzzKazzz 2005/06/14 13:08 .NETの場合コードページ932のエイリアスがShift_JISなのでその通りに取って良いかと思います。0つまりデフォルトでも932でShift_JISと戻ってくるはずです。

KazzzKazzz 2005/06/14 13:23 >とはいえこれは大仰に過ぎるかな。
まあ、現状utf-8を使うかJava側と名前が違うのを意識して.NET側はShift_JISを使う等で逃げることは可能なので致命的ではありませんが開発者としてはIANAがある以上全てIANA名で統一して欲しいというのが本音です。あとこれは.NET側だけの責任ではありませんが現状ではJavaと.NETでShift_JISの意味が変わってくるのも嫌なところです。

artonarton 2005/06/14 19:38 おお、これは素晴らしい。
>IANAがある以上全てIANA名で統一して欲しい
同意。

中博俊中博俊 2005/06/15 11:22 .Netじゃないのでなんとも。
OS出荷時期の問題もありますので。
WIndows-31Jがいつ制定されたのか分かりませんが(^^
すべてのエンコードがサポートされているわけでもなんでもないので微妙(^^;;

スパム対策のためのダミーです。もし見えても何も入力しないでください
ゲスト


画像認証

トラックバック - http://d.hatena.ne.jp/Kazzz/20050614/p1