2007年03月15日

バイナリなコマンドライン引数

久々にしてちょっとお馬鹿っぽい一つの解決。

VBレスキュー(花ちゃん)のVB.NET・VB2005用掲示板 の、コマンドラインの引数について というスレッドを見て思いついたのですが。

コマンドライン引数には文字列しか使えないので、オブジェクトは渡せません。

さて、IFormatter や XmlSerializer などを使えばオブジェクトを永続化でき、他のアプリケーションともやり取りできます。でも SoapFormatter や XmlSerializer は長ったらしくなるのでコマンドライン引数の文字数制限に引っかかりそうな気がするし、BinaryFormatter はそれ以前にバイナリなんで問題外です。

ここでふと思い出したのが、Base64 です。これならバイナリを文字列に変換できます。使用される文字は MSDN の Convert.ToBase64String メソッドの解説 に以下のように書かれています。

Base64 形式の文字を 0 から昇順で並べた場合、大文字の "A" 〜 "Z"、小文字の "a" 〜 "z"、数字の "0" 〜 "9"、および "+" と "/" の記号の順になります。値として解釈されない文字 "=" は、文字列末尾の埋め込み用に使用されます。

半角空白やダブルクォーテーションが含まれておらず、全く普通にコマンドライン引数として利用可能な文字のみが使われています。おお、これならいける。

つまり、BinaryFormatter でシリアライズし、それを Base64 でエンコーディングして引数に渡す。渡された側はデコードしてデシリアライズする。という手順を踏めば問題なく受け渡し可能と言うことになります。

早速コードを書いてみましょう。エラー処理なんかやってないのでデシリアライズ時は注意。使い方は、まあ言うまでもないですよね。当然の事ながら、引数として渡すアプリケーションと受け取るアプリケーションは双方がこの Hoge クラスを定義しているアセンブリを参照しておく必要があります。

XmlSerializer なら、型と名前さえ同じなら同じクラス(同じクラスであるというのはつまり端的に言うとでなくてもデシリアライズできるので、自由度が高いかも知れません。XmlSerializer は XmlSerializer で難しい部分もありますけど。

// C#
using System;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
[Serializable] public class Hoge {
    public string Name;
    public string Value;
    public string ToSerializedString() {
        MemoryStream buffer = new MemoryStream();
        BinaryFormatter formatter = new BinaryFormatter();
        formatter.Serialize(buffer, this);
        return Convert.ToBase64String(buffer.ToArray());
    }
    public static Hoge FromSerializedString(string serialized) {
        byte[] buffer = Convert.FromBase64String(serialized);
        BinaryFormatter formatter = new BinaryFormatter();
        return (Hoge)formatter.Deserialize(new MemoryStream(buffer));
    }
}
' VB
Imports System
Imports System.IO
Imports System.Runtime.Serialization.Formatters.Binary
<Serializable> Public Class Hoge
    Public Name As String
    Public Value As String
    Public Function ToSerializedString() As String
        Dim buffer As New MemoryStream()
        Dim formatter As New BinaryFormatter()
        formatter.Serialize(buffer, Me)
        Return Convert.ToBase64String(buffer.ToArray())
    End Function
    Public Shared Function FromSerializedString(ByVal serialized As String) As Hoge
        Dim buffer As Byte() = Convert.FromBase64String(serialized)
        Dim formatter As New BinaryFormatter()
        Return DirectCast(formatter.Deserialize(New MemoryStream(buffer)), Hoge)
    End Function
End Class
posted by Hongliang at 23:49| Comment(0) | TrackBack(0) | .NET | このブログの読者になる | 更新情報をチェックする
この記事へのコメント
コメントを書く
お名前:

メールアドレス:

ホームページアドレス:

コメント:

認証コード: [必須入力]


※画像の中の文字を半角で入力してください。

この記事へのトラックバック

ここ(hongliang.seesaa.net)で公開しているものについて、利用は自由に行って頂いて構いません。改変、再頒布もお好きになさって下さい。利用に対しこちらが何かを要求することはありません。

ただし、公開するものを使用、または参考したことによって何らかの損害等が生じた場合でも、私はいかなる責任も負いません。

あ、こんなのに使ったってコメントを頂ければ嬉しいです。

×

この広告は1年以上新しい記事の投稿がないブログに表示されております。