平常我们使用文件存储程序数据时,一般需要将数据转换为文本等存储,等到需要使用的时候再从文件读取,然后重新构建类或结构或数组等对象。这样的转换和重建即浪费了时间效率不够高又导致容易出错,其实最近由于研究二进制文件的存取,我找到了序列化存取的方法。 序列化存取可以做到类对象、结构、数组等内存实体整体保存为二进制的文件,而不需转换,读取的时候,通过反序列化直接从文件构建对象,而不需要重新通过转换而来的数据构建,这样既节省了转换时间,运行速度又比较快。 简要说明一下,序列化主要是通过实现System.Runtime.Serialization.IFormatter接口的System.Runtime.Serialization.Formatters.Binary.BinaryFormatter类来实现的,其中的void Serialize(Streamst, object ob)来实现序列化,这个函数就可以将object对象ob序列化为二进制流输入给Stream流st,这个方法有重载,具体看MSDN,但对于我们只想简单序列化,这样写也就够了。object Deserialize(Stream st)这个方法可以实现反序列化,从给定的Stream流st中反序列化出一个object对象,只需强制转换为目标对象就可以了。 为了说明问题,新建了一个示例工程(winForm程序),就一个界面,实现一个类的存和取如下(如果要序列化存储结构和数组只需要将Person对象换成相应对象即可,另外设计器自动生成的代码没有贴出来):
[code=csharp]using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
namespace 序列化的二进制文件存取
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
/// <summary>
/// 存储文件位置
/// </summary>
public static string savePath = "序列化存储文件.data";//指定存储在程序启动文件夹下的"序列化存储文件.data"内
/// <summary>
/// 存
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void button_Save_Click(object sender, EventArgs e)
{
//新建Person类对象
Person newPerson = new Person();
newPerson.name = textBox_name.Text;
newPerson.age = Convert.ToInt32(textBox_age.Text);
newPerson.grade = Convert.ToInt32(textBox_grade.Text);
//这个对象用于序列化对象
System.Runtime.Serialization.Formatters.Binary.BinaryFormatter binaryFormatter
= new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
////或者用这个接口创建实例也可以
//System.Runtime.Serialization.IFormatter binaryFormatter
// = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
////序列化person对象newPerson,先转化为二进制再存为文件
//System.IO.MemoryStream ms = new System.IO.MemoryStream();
//binaryFormatter.Serialize(ms, newPerson);
//byte[] buffer = ms.GetBuffer();
//System.IO.Stream st = new System.IO.FileStream(savePath, System.IO.FileMode.Create);
//st.Write(buffer, 0, buffer.Length);
//st.Close();
//序列化person对象newPerson并存为文件
System.IO.Stream st = new System.IO.FileStream(savePath, System.IO.FileMode.Create);//新建文件流
binaryFormatter.Serialize(st, newPerson);//序列化类对象,并输入流
st.Close();
}
/// <summary>
/// 取
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void button_Read_Click(object sender, EventArgs e)
{
//这个对象用于反序列化对象
System.Runtime.Serialization.Formatters.Binary.BinaryFormatter binaryFormatter
= new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
//浏览存储的对象文件
OpenFileDialog op=new OpenFileDialog(){Filter="PerSon类文件(*.data)|*.data",InitialDirectory=Application.StartupPath};
op.ShowDialog();
if (System.IO.File.Exist(op.FileName))//如果浏览到文件
{
System.IO.Stream st = new System.IO.FileStream(op.FileName, System.IO.FileMode.Open);//指向数据文件的二进制流
Person per = (Person)binaryFormatter.Deserialize(st);//反序列化,得到的是一个object对象,需要强制转换
textBox_Show.Text = per.ToString();//显示对象信息
st.Close();
}
else
textBox_Show.Text = "没有相关文件!";
}
}
/// <summary>
/// 类示例
/// </summary>
[Serializable]//加上这个属性后此类创建的对象才能被序列化
class Person
{
public string name { set; get; }
public int age { set; get; }
public int grade { set; get; }
public override string ToString()
{
return "名字:" + name.ToString() + "\r\n年龄:" + age.ToString() + "\r\n年级:" + grade.ToString();
}
}
}
[/code]
|