.net下二进制序列化的格式分析

作者:zfive5

email:zfive5@yahoo.com.cn

 

相应c#下的序列化代码如下所示,程序把序列化后的数据存入了一个指定的文件file.bin里,分析这个文件数据主要为了能让非.Net下的应用程序读取序列化后数据,这有助于.net与其他语言平台的交互.

 

using System;

using System.Drawing;

using System.Collections;

using System.ComponentModel;

using System.Windows.Forms;

using System.Data;

 

namespace WindowsApplication2

{

    [Serializable]

    public class Object5

    {

        public int i1 = 0;

        public int i2 = 0;

        public float f3=0;

        public string str;

    }

 

    public class Form1 : System.Windows.Forms.Form

    {

        private System.Windows.Forms.Button button1;

        private System.ComponentModel.Container components = null;

 

        public Form1()

        {

            InitializeComponent();     

}

 

        protected override void Dispose( bool disposing )

        {

            if( disposing )

            {

                if (components != null)

                {

                    components.Dispose();

                }

            }

            base.Dispose( disposing );

        }

 

        #region Windows 窗体设计器生成的代码

        private void InitializeComponent()

        {

            this.button1 = new System.Windows.Forms.Button();

            this.SuspendLayout();

            this.button1.Location = new System.Drawing.Point(72, 72);

            this.button1.Name = "button1";

            this.button1.Size = new System.Drawing.Size(128, 32);

            this.button1.TabIndex = 0;

            this.button1.Text = "button1";

            this.button1.Click += new System.EventHandler(this.button1_Click);

            this.AutoScaleBaseSize = new System.Drawing.Size(6, 14);

            this.ClientSize = new System.Drawing.Size(292, 273);

            this.Controls.Add(this.button1);

            this.Name = "Form1";

            this.Text = "Form1";

            this.ResumeLayout(false);

 

        }

        #endregion

        [STAThread]

        static void Main()

        {

            Application.Run(new Form1());

        }

        private void button1_Click(object sender, System.EventArgs e)

        {

            Object5 obj = new Object5();

            obj.i1 = 128;

            obj.i2 = 24;

            obj.f3=1.3f;

            obj.str = "Some String";

 

            double   d1=1.3d;

            float    f1=1.3f;

            int      i1=1;

            string   s1="HelloWorld";

 

            System.Runtime.Serialization.IFormatter formatter = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();

            System.IO.Stream stream = new System.IO.FileStream("File.bin", System.IO.FileMode.Create, System.IO.FileAccess.Write, System.IO.FileShare.None);

            formatter.Serialize(stream, obj);

            formatter.Serialize(stream,d1);

            formatter.Serialize(stream,f1);

            formatter.Serialize(stream,i1);

            formatter.Serialize(stream,s1);

 

            stream.Close();

            formatter=null;

        }

    }

}

文件内容如下图所示:

注解:

1 00 01 00 00 00 FF FF FF FF 01 00 00 00 00 00 00 00 序列化头,经过实践分析,这部分基本在每个序列化后的数据都一样,下面也可以看到与其他的一样

2 0C 02 被序列化后对象描述信息的表示符

3 00 00 00 5181)长度,(注意是大端的4位整型),说明后面对象描述信息的长度

4 )自定义对象的描述信息,分析时可以忽略,长度为81个字符(前一项以说明)

5 05 01自定义对象的表示符 .

6 00 00 00 1b (27)自定义对象类描述信息的长度

7 )自定义对象的描述信息,主要类的符号表示 (“WindowsApplication2.Object5”)

8 )自定义对象中的成员条目,例如在上面定义的对象中有四项,分别为intintflaotstring

9 02 长度为2int i1成员

10 )对应成员名称的定义标示 “i1”

11 )同9

12 )同10

13 )同 9

14 )同 10

15 )同 9

16 )同10

17 )说明自定义对象的各个定义项目是值对象还是其他类型,一共4个字节,00为值对象

 01为字符对象 在上面定义的对象为 int i1 int i2 float f1 string str 对应为 00 00 00 01

 

18)说明17)对应的字段的类型 分别为 int 08  int 08  int 0b

19 02 00 00 00 固定,说明其他数据的开始

20)对应obj.i1的值 80 00 00 00128、小端格式)

21)对应obj.i2的值 18 00 00 00 24、小端格式)

22)对应obj.f1的值 66 66 a6 3f  1.3的浮点格式)

2306 03 对象string标示符,说明它是string对象

242500 00 00 0b string对象的长度11(大端),值为“Some String”

260b表示一个对象序列的结束。

27)同1

2804 01 double类型的表示符号

2900 00 00 0d13 类型长度(大端)

30)对象定义标示符( “System.Double”

31) 01 00 00 001)包含一个成员

3207 7)成员的定义标示符长度

33) 成员的定义符号 “m_value”

34) 00  说明是值类型  06说明是double类型

35CD CC CC CC CC CC F4 3F  double类型对应的数值

360b一个序列对象的结束

 

其他的注释分析就在这里不在重复了,原理都一样的!

经过测试得到的类型与表示符的部分对应关系,如下所示

bool 01

byte 02

uint 0f

char 03

ulong 10

ushort  0e

decimal 05

int     08

sbyte   0a

short   07

double  06

float   0b

long    09

string  06 03 /06 04

 

 

值类型 00

string 01

object 02

[]     07

struct 04

 

这里分析只是一部份!主要随着对象的复杂,会涌现出没有分析到的标示符,如果你发现新的请给我发一封电子邮件,万分感谢!

这时大家也可以体会出为什么xml序列化的存在了,不同系统实现数据想要容易的多了,xml有一个缺点就是数据量大.这是与二进制序列化所不能比的!

Xml序列化代码如下:

System.Xml.Serialization.XmlSerializer formatter=new System.Xml.Serialization.XmlSerializer(obj.GetType());

 

对象Object5序列化后的xml文件如下:

<?xml version="1.0"?>

<Object5 xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">

  <i1>128</i1>

  <i2>24</i2>

  <f3>1.3</f3>

  <str>Some String</str>

</Object5>

简单吧!

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
.NET Core 中,我们可以使用以下两种方式进行对象序列和反序列: 1. BinaryFormatter:BinaryFormatter 是 .NET Framework 中常用的一种序列方式,它可以将对象序列二进制格式,也可以将二进制格式序列为对象。在 .NET Core 中,BinaryFormatter 仍然可以使用,但是需要注意的是,它只支持 .NET Framework 中的类型,不支持 .NET Core 中新增的类型。 以下是使用 BinaryFormatter 进行序列和反序列的示例代码: ```csharp using System; using System.IO; using System.Runtime.Serialization.Formatters.Binary; [Serializable] public class Person { public string Name { get; set; } public int Age { get; set; } } public class Program { public static void Main() { // 创建一个 Person 对象 var person = new Person { Name = "Tom", Age = 30 }; // 将 Person 对象序列为 byte[] var formatter = new BinaryFormatter(); using (var stream = new MemoryStream()) { formatter.Serialize(stream, person); var bytes = stream.ToArray(); } // 将 byte[] 反序列为 Person 对象 using (var stream = new MemoryStream(bytes)) { var p = (Person)formatter.Deserialize(stream); Console.WriteLine($"Name: {p.Name}, Age: {p.Age}"); } } } ``` 2. Newtonsoft.Json:Newtonsoft.Json 是一个流行的 JSON 序列/反序列库,它支持 .NET Core 中的所有类型,并且性能也非常不错。我们可以通过 NuGet 引用 Newtonsoft.Json 库,并使用 JsonConvert 类进行序列和反序列。 以下是使用 Newtonsoft.Json 进行序列和反序列的示例代码: ```csharp using System; using Newtonsoft.Json; public class Person { public string Name { get; set; } public int Age { get; set; } } public class Program { public static void Main() { // 创建一个 Person 对象 var person = new Person { Name = "Tom", Age = 30 }; // 将 Person 对象序列为 JSON 字符串 var json = JsonConvert.SerializeObject(person); Console.WriteLine(json); // 将 JSON 字符串反序列为 Person 对象 var p = JsonConvert.DeserializeObject<Person>(json); Console.WriteLine($"Name: {p.Name}, Age: {p.Age}"); } } ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值