- PR -

設定情報の保存法について

投稿者投稿内容
笊頭刹那
ベテラン
会議室デビュー日: 2005/10/17
投稿数: 55
お住まい・勤務地: オーストラリア
投稿日時: 2005-11-12 16:07
お世話になっています刹那です。

スキン情報ファイルを作っています、いままではiniファイルを使用していたのですが速度面の問題からXmlファイルを使用しようと思いました。

そこで質問なのですが
コード:
class skin
{
    public Rectangle Size
    public Image     Image;
    public class Window
    {
        public Rectangle Size
    }
}


のような構造のクラスがあったとします、XmlなのでImageはそのまま書き込めないので
コード:
<skin>
    <Size>
        <Width>10</Width>
        <Height>10</Height>
    </Size>
    <Image>.\\images\\sample.bmp</Image>
    <Window>
        <Size>
           <Width>10</Width>
           <Height>10</Height>
        </Size>
     </Window>
</Skin>


というXmlファイルにしたとします、この場合どのように読み込みコーディングするのが良いのでしょうか?

1, 力技で読み込む
コード:
skin.Width = int.Parse(dc.GetElementsByTagName("Width","")[0].Value);
skin.Size.Width = int.Parse(dc.GetElementsByTagName("Width","Size")[0].Value);
...


コーディング大変ですよね…

2, シリアライズを利用する
Imageに[System.Xml.Serialization.XmlIgnoreAttribute]を付けてImageFileという新しい項目を作りシリアライズ。
デシリアライズ後にImageFileの値からImageを作成。

Imageがかなりあるので余計な文字列変数が大量になる…きれいなコードとはいえないかなと思う。

3, もっとすばらしい方法
が、知りたいんです。

4, Xmlファイルを使わないいい方法。
こういう状況ではXmlを使わないほうが良いというのであれば教えていただきたいです。

スキンファイルはなるべく簡単に編修できるようにしたいのでバイナリ形式は避けたいです、メモ帳で作成可能にしたいので。(独自エディタを作ればいいんですがね汗)

よろしくお願いします。
囚人
ぬし
会議室デビュー日: 2005/08/13
投稿数: 1019
投稿日時: 2005-11-12 16:53
こんにちは。

skin 構造体にこだわりがなければ、(型付) DataSet を使うとか、ですかね。
Jubei
ぬし
会議室デビュー日: 2002/03/02
投稿数: 830
お住まい・勤務地: 関西
投稿日時: 2005-11-12 16:57
諸農です。

目的に合っているかどうかは判りません。
シリアライズサンプルです。

コード:
//設定情報クラス
    [Serializable]
    public class MyInfo:ISerializable  
    {
        public Rectangle size;
        public Image image;

        public void GetObjectData(SerializationInfo si,StreamingContext sc)
        {
            si.AddValue("image",image);
            si.AddValue("size",size);
        }

        private MyInfo(SerializationInfo si,StreamingContext sc)
        {
            image = (System.Drawing.Image)si.GetValue("image",typeof(Image));
            size = (System.Drawing.Rectangle)si.GetValue("size",typeof(Rectangle));
        }
        public MyInfo()
        {
        }
    }

//使う側
private MyInfo mi;
private void button1_Click(object sender, System.EventArgs e)
{
    mi = new MyInfo();
    mi.image = Image.FromFile("ABC.jpg");
    mi.size = new Rectangle(new Point(0,0),mi.image.Size);

    FileStream fs = new FileStream("ABC.xml",FileMode.Create);
    SoapFormatter sf = new SoapFormatter();
    sf.Serialize(fs,mi);
    fs.Close();
}

private void button2_Click(object sender, System.EventArgs e)
{
    FileStream fs = new FileStream("ABC.xml",FileMode.Open);
    SoapFormatter sf = new SoapFormatter();
    mi = (MyInfo)sf.Deserialize(fs);
    fs.Close();
    pictureBox1.Image = mi.image;
}



イメージはBase64されているので、テキストエディタで開くことが出来ます。


_________________
諸農和岳
Powered by Turbo Delphi & Microsoft Visual Studio 2005

十兵衛@わんくま同盟
http://blogs.wankuma.com/jubei/
笊頭刹那
ベテラン
会議室デビュー日: 2005/10/17
投稿数: 55
お住まい・勤務地: オーストラリア
投稿日時: 2005-11-12 17:16
>囚人さん
DataSet初めて聞いた言葉なので調べてきます、情報提供ありがとうございました。

>Jubeiさん
えっと、第三者がメモ帳などで開いて編集できるようにしたいのでイメージの値はイメージのファイル名にしたいのです。
ですが、イメージをテキストファイルに保存できるというのは驚きです(もちろんサイズ増えるだろうけど)また違う局面でこの技を利用させてもらうかもしれません、ありがとうございました。
笊頭刹那
ベテラン
会議室デビュー日: 2005/10/17
投稿数: 55
お住まい・勤務地: オーストラリア
投稿日時: 2005-11-12 17:21
いやちょっと待てよ…

コード:
private MyInfo(SerializationInfo si,StreamingContext sc)
{
     image = new Bitmap(si.GetValue("image",typeof(string)));
     size = (System.Drawing.Rectangle)si.GetValue("size",typeof(Rectangle));
}


としたらどうなんだ???デシリアライズしか行わないのだから…

これに問題ってありますかね?シリアライズはできませんが、シリアライズするつもり無いので(シリアライズするとすればシリアライズしたXmlファイルに後でImageを追加するとか?)
Jitta
ぬし
会議室デビュー日: 2002/07/05
投稿数: 6267
お住まい・勤務地: 兵庫県・海手
投稿日時: 2005-11-12 19:08
パッと見て、どれが何の値かわかるような XML にはならないので、目的にはあわないでしょう。

バージョン管理とかもできて、便利なんですけどね。
笊頭刹那
ベテラン
会議室デビュー日: 2005/10/17
投稿数: 55
お住まい・勤務地: オーストラリア
投稿日時: 2005-11-12 19:44
>Jitta
…すいませんおっしゃっている意味がよく分からないのですが(汗。

スキン情報ファイルをXml形式で書くとぱっと見てどれが何の値か分かりにくいのでスキン情報ファイルにXmlファイルを使用するというのは目的に合わない

という意味ですか???

あ、今書いてて思いましたがシリアライズで画像をBase64で行う場合って意味ですね、きっと…?
Jubei
ぬし
会議室デビュー日: 2002/03/02
投稿数: 830
お住まい・勤務地: 関西
投稿日時: 2005-11-12 22:41
諸農です。

囚人さんが提案されている方法だとこんな感じかな。

コード:
    //設定を保存する処理
    DataSet ds = new DataSet("MyInfoDS");
    ds.ReadXmlSchema("MyInfoSchema.xsd");
    DataTable dt = ds.Tables["MyInfo"];
    DataRow dr = dt.NewRow();
    dr["ImageName"] = "ABC.jpg";
    FileStream im = File.OpenRead("ABC.jpg");
    byte[] bs = new byte[im.Length];
    im.Read(bs,0,bs.Length);
    dr["Image"] = Convert.ToBase64String(bs,0,bs.Length);
    dr["size"] = new Rectangle(new Point(0,0),Image.FromFile("ABC.jpg").Size);
    dt.Rows.Add(dr);
    System.Xml.XmlDataDocument xd = new System.Xml.XmlDataDocument(ds);
    FileStream fs = new FileStream("ABC.xml",FileMode.Create);
    xd.Save(fs);
    fs.Close();



    //設定を読み出す処理
    System.Xml.XmlDataDocument xd = new System.Xml.XmlDataDocument();
    xd.DataSet.ReadXmlSchema("MyInfoSchema.xsd");
    FileStream fs = new FileStream("ABC.xml",FileMode.Open);
    xd.Load(fs);
    fs.Close();
    DataTable dt = xd.DataSet.Tables["MyInfo"];
    string b64 = (string)dt.Rows[0]["Image"];
    byte[] bs = Convert.FromBase64String(b64);
    MemoryStream ms = new MemoryStream(bs);
    pictureBox1.Image = Image.FromStream(ms);
    ms.Close();



VS2003だとDataSetでスキーマを作っておかないといけないのが面倒くさいですね。
VS2005だとDataTableをXMLで保存できるんですよね。

#なぜか画像そのものの保存と読み出しにこだわる私(^^;
#他意はありませんm(_ _)m
_________________
諸農和岳
Powered by Turbo Delphi & Microsoft Visual Studio 2005

十兵衛@わんくま同盟
http://blogs.wankuma.com/jubei/

スキルアップ/キャリアアップ(JOB@IT)