[C#] シリアライズ(Serialization)をする方法


Devlopment note / C#    作成日付 : 2020/04/30 19:32:04   修正日付 : 2020/04/30 19:32:04

こんにちは。明月です。


この投稿はC#でシリアライズ(Serialization)をする方法に関する説明です。


シリアライズとはメモリに割り当てしているクラスのデータをバイナリ化することです。つまり、クラス内部で変数のデータをすべてbyteタイプに変換することだと思えば良いです。

シリアライズは昔にたくさん使った記憶がありますが、最近はシリアライズよりJsonタイプに変換してデータ化することがトレンドなので、最近はよく使わないみたいです。

link - [C#] Newtonsoft.JSONライブラリを利用してJsonデータ構造を扱う方法


でも、Newtonsoft.Jsonを利用してデータをJsonタイプに変換することはクラスのPublicタイプだけ変換するし、データをすべてStringタイプに変換するので、限界があります。

シリアライズはPublicデータだけではなく、Privateも構造化するし、クラス自体をすべてByteタイプに変換することなので、クラス自体を格納することではよいです。


でも、シリアライズも短所があります。バイナリ化するので、当該なデータを人が読みにくいです。なのでメモ帳でデータ変更ができないです。

また、クラス自体を変換しましたから、クラスが変更がある場合に復元ができない可能性もあります。

Jsonも場合はプログラム言語に関係しずに、読み込む移植性がよいですが、シリアライズはC#で作成したらC#しか読み込まれないです。


正確にはクラス変更や他のプレートフォームでも読み込まられないことではないですが、データ漏れが発生したり、データが可笑しくなる可能性があります。

つまり、バグ発生する可能性があることです。


仕様によってシリアライズがよいかJsonを使うかを正しく選択して使う方がよいです。

Copy!
 [Source view] Program.cs
using System;
using System.IO;
// シリアライズのライブラリ
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
namespace Example
{
// シリアライズを使うために、当該クラスのアトリビュートに宣言する。
[Serializable]
// テストクラス
class Node
{
// 変数 - データ格納はコンストラクタで出力はPrint関数だけ。
private string data;
// コンストラクタ
public Node(string data)
{
this.data = data;
}
// 出力関数
public void Print()
{
// コンソールに出力
Console.WriteLine(this.data);
}
}
class Program
{
// 実行関数
static void Main(string[] args)
{
// テストクラスを宣言
// node.dataには「Test」データが格納される
var node = new Node("Test");
// シリアライズフォーマットクラス
var formatter = new BinaryFormatter();
// クラスをシリアライズして格納する変数
byte[] data;
// Streamでシリアライズしてdata変数にデータをコピーする。
using (var stream = new MemoryStream())
{
// クラスをStreamタイプに変換
formatter.Serialize(stream, node);
// 変数のサイズを割り当てする。
data = new byte[stream.Length];
// Streamのデータをbyteタイプに変換
data = stream.GetBuffer();
}
// シリアライズしたデータをファイルに格納する。
using (var stream = new FileStream("c:\\work\\Serializable.dat", FileMode.Create, FileAccess.Write))
{
stream.Write(data, 0, data.Length);
}
// データを読み込む
var info = new FileInfo("c:\\work\\Serializable.dat");
// データを再割り当てする。
data = new byte[info.Length];
// ファイルからデータを読み込む。
using (var stream = info.OpenRead())
{
stream.Read(data, 0, data.Length);
}
// Streamでデータをデシリアライズする。
using (MemoryStream stream = new MemoryStream())
{
// byteをStreamに読み込む。
stream.Write(data, 0, data.Length);
// Stream seekを最初に移動する。
stream.Seek(0, SeekOrigin.Begin);
// クラスをデシリアライズしてNodeクラスにキャストする。
node = (Node)formatter.Deserialize(stream);
}
// データを出力する。
node.Print();
Console.WriteLine("Press any key...");
Console.ReadKey();
}
}
}

Nodeというクラスをシリアライズしてbyte[]タイプに変換しました。変換してファイルに格納します。

また、格納したファイルを読み込んでデシリアライズでbyte[]データをクラスタイプに変換します。


ファイルをメモ帳で開きました。


人が解析することでは無理があります。


ここまでC#でシリアライズ(Serialization)をする方法に関する説明でした。


ご不明なところや間違いところがあればコメントしてください。

最新投稿