MASATOの開発日記


前の開発日記 次の開発日記 一覧

2002/11/02

最近、データの暗号化をしたり、ハッシュを取ったりという作業をC#とJava2(1.4)の両方で やってみました。
一番大変だったのが、BASE64によるエンコード。なぜかJavaはBASE64を扱うクラスが無いのです。 .NET Frameworkクラスライブラリにはあたりまえーのようにあります。 XMLを扱うようになってくるとBASE64はかなり必須だと思うのですが、 なぜ標準のクラスライブラリに付けてくれないんでしょうね・・・
.NET Frameworkクラスライブラリにあって、Javaのクラスライブラリには無い! という機能って結構あるような気がします。逆もあるとは思いますが、あまり目立ちません。 SunとMicrosoftの開発リソース(開発者の数)の違いが感じられます。

BASE64によるエンコード/デコードのサンプルソースはあちこちにありますので それを持って来れば問題無いのですが、 そのソースを勝手に使ってよいかどうか明記されていないものはあまり使いたくありません。 標準のクラスライブラリにつけてくれれば何も心配は無いのですが・・・

そういえば、この開発日記に登場するコードも、利用規約が何もありませんね。 書いておかねば・・・

URN namespace duri

XMLを扱っていると、しばしばどんな名前のNameSpaceにするか考える必要がありました。
細かい話は省きますが、私が作成したアプリケーションを表す世界でユニークな文字列が必要になるのことがあります。
例えば、私がTestというアプリケーションを作ったとして、それを表す文字列を考えてみますと・・・

MASATO/Test

うーむ。MASATOという名前の人は世の中に山ほどいる訳ですし、そういった人が同じ名前をつけるかもしれません。

http://www.yks.ne.jp/~masato/Test

このURLが何かを指しているわけではありませんが、現在このURLを扱えるのは 世の中に私一人でしょう。よって、「世界でユニークな文字列」にかなり近づきました。 しかし、もしかしたら将来このyks.ne.jpのmasatoアカウントが、他の人の手に渡るかもしれません。 そこまで考えると、この文字列も確実とは言えません。

urn:duri:2002:http://www.yks.ne.jp/~masato/Test

これで完璧です。 この複雑な文字列は、2002年が始まった瞬間のhttp://www.yks.ne.jp/~masato/Testを指しています。 これはまさしく「世界でユニークな文字列」です。 2002年が始まった瞬間はyks.ne.jpのmasatoアカウントは私の手にあったり、 今後どうあれこの事実は動かせません。
この文字列は、一応RFC2141に記述されたURNの形式に適合しており、 さらにはURN namespace duriの仕様(こちらはまだドラフト段階です)にも適合しているということで、 一応公式な文字列です。

XMLシリアライザ

環境Visual C#.NET

.NET Frameworkには、リフレクションという機能があります。 これは、このオブジェクトのクラスにどのようなフィールドがあるか?というような プログラム自身の情報を、実行時に取得する方法です。
これを使うと、クラスのフィールド名一覧を出力するようなプログラムが作れます。 C++では、実行ファイル生成時に変数名が失われているので、 同じことはできません。つまり、C++にはリフレクション機能はありません。

このリフレクションを使ったと思われるのが、以下に解説するXMLシリアライザです。 リフレクションをうまく使うとこんなことができるんだなぁ、という見本になるのではないかと思います。

まずは、シリアライズするために適当なクラスを作成します。 publicなclassである必要がありますので注意して下さい。publicでないと、XmlSerializerのコンストラクタが例外を投げます。

public class Test {
  public string name;
  public string password;
  public int cost;
}

では、次にこれをXmlSerializerでシリアル化してみましょう。

using System.Xml.Serialization;
using System.IO;
// 中略
  Test test = new Test();
  test.name = "名前";
  test.password = "パスワード";
  test.cost = 100;
  XmlSerializer serializer = new XmlSerializer(typeof(Test));
  Stream outstream = new FileStream("test.xml", FileMode.Create, FileAccess.Write);
  serializer.Serialize(outstream, test);
  outstream.Close();
// 後略

そうすると、test.xmlというファイルが作成されているはずです。 これのエンコーディングスキームは(デフォルトでは)UTF-8です。 UTF-8を解釈できるテキストエディタでtest.xmlの中身を覗いてみると・・・

<?xml version="1.0"?>
<Test xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <name>名前</name>
  <password>パスワード</password>
  <cost>100</cost>
</Test>

おお!たったこれだけでXML文書として保存できました。 しかもインデントが入っていて見やすくなっていたりします。

もちろん読込むこともできます。

  XmlSerializer desirializer = new XmlSerializer(typeof(Test));
  Stream instream = new FileStream("test.xml", FileMode.Open, FileAccess.Read);
  Test test2 = (Test)desirializer.Deserialize(instream);
  instream.Close();

これでtest2には、先ほどのtestの内容がそのまま入っています。

たったこれだけで、オブジェクトをXML文書として保存できるとはなかなか便利そうです。 とりあえずアプリケーションの設定の保存なんかには役立ちますね。 考えれば他にも様々な使い道がありそうです。

(2002/12/04) XML文章をXML文書に修正。

(2003/01/08) public classについて注意点を追加。コードのミスを修正。

前の開発日記 次の開発日記 一覧