需求描述
- 构建一个Student类
包括姓名、学号、分数,然后在控制台中输入N个学生的上述信息,并将信息保存到文件。 - 创建一个文本文件
将Student对象的信息写入到文本文件。如果该文件已存在则将该文件备份,再写入新的数据。 - 对象序列化
Student对象储存到ArrayList对象中,然后通过序列化,将ArrayList对象中的Student对象保存到文件中。 - 读出文件中Student对象信息
思路分析
在这之前并不太了解C#的序列化,于是百度一下。
得一百度知道解答: c#中序列化是什么,怎么用,什么情况下用,不用有什么后果?
c#中序列化就是把一个对象保存到一个文件或数据库字段中去。
序列化用途:
1、在进程下次启动时读取上次保存的对象的信息
2、在不同的AppDomain或进程之间传递数据
3、在分布式应用系统中传递数据
常见的序列化的方法:
1、BinaryFormatter
2、SoapFormatter
3、XML序列化
用法:
BinaryFormatter的用法大致如下:
//BinaryFormatter将对象序列化到文件中
List<string> inputList = new List<string>() { "str1","str2","str3"};
using (FileStream fsWriter = new FileStream(@"tmp.dat",FileMode.Create,FileAccess.Write))
{
BinaryFormatter bf = new BinaryFormatter();
//序列化
bf.Serialize(fsWriter, inputList);
}
//BinaryFormatter将文件中的数据反序列化出来
List<string> outputList = new List<string>();
using (FileStream fsReader = new FileStream(@"tmp.dat",FileMode.Open,FileAccess.Read))
{
BinaryFormatter bf = new BinaryFormatter();
//反序列化
outputList = (List<string>)bf.Deserialize(fsReader);
}
XML序列化的用法大致如下:
//xml序列化到tmp.xml文件中
List<string> inputList = new List<string>() { "str1","str2"};
using (FileStream fsWriter = new FileStream(@"tmp.xml",FileMode.Create,FileAccess.Write))
{
XmlSerializer xs = new XmlSerializer(typeof(List<string>));
xs.Serialize(fsWriter, inputList);
}
//从tmp.xml文件中反序列化出来
List<string> outputList = new List<string>();
using (FileStream fsReader = new FileStream(@"tmp.xml",FileMode.Open,FileAccess.Read))
{
XmlSerializer xs = new XmlSerializer(typeof(List<string>));
outputList = xs.Deserialize(fsReader) as List<string>;
}
总结:
两个的用法大致如下:
序列化:
1.得到一个存储对象的类型
2.创建一个写入文件流
3.定义要序列化的类型
4.调用序列化方法反序列化:
1.定义一个装载对象的类型
2.创建一个读出文件流
3.定义要反序列化的类型
4.调用反序列化方法BinaryFormatter类进行序列化和反序列化,以缩略型二进制格式写到一个文件中去,速度比较快,而且写入后的文件已二进制保存有一定的保密效果。标记为NonSerialized的其他所有成员都能序列化。
采用xml序列化的方式只能保存public的字段和可读写的属性,对于private等类型的字段不能进行序列化。
二进制序列化的优点:
1. 所有的类成员(包括只读的)都可以被序列化;
2. 性能非常好。XML序列化的优点:
1. 互操作性好;
2. 不需要严格的二进制依赖;
3. 可读性强
另外还受助于这片博文C# ArrayList用BinaryFormatter序列化和反序列化进行文件读写的一个简单例子
参考代码
Student.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace StudentManager
{
[Serializable]
class Student
{
private string name;
private int num;
private int score;
public Student()
{
name = "Anonymous";
num = 0;
score = 0;
}
public Student(string name, int num, int score)
{
this.name = name;
this.num = num;
this.score = score;
}
#region 访问器
public string Name
{
get { return name; }
set { name = value; }
}
public int Num
{
get { return num; }
set { num = value; }
}
public int Score
{
get { return score; }
set { score = value; }
}
#endregion
}
}
Program.cs
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net.Configuration;
using System.Runtime.Serialization.Formatters.Binary;
using System.Text;
using System.Threading.Tasks;
namespace StudentManager
{
class Program
{
static void Main(string[] args)
{
int sum = 0;
string tempStr;
Console.WriteLine("Input student's sum:");
tempStr = Console.ReadLine();
sum = Convert.ToInt32(tempStr);
Console.WriteLine("sum = {0}",sum);
ArrayList studentList = new ArrayList(sum);
// input students' data
for (int i = 1; i <= sum; i++)
{
string name;
int num, score;
Console.WriteLine("Input the data of student #{0}", i);
Console.Write("Name: ");
name = Console.ReadLine();
Console.Write("Number: ");
tempStr = Console.ReadLine();
num = Convert.ToInt32(tempStr);
Console.Write("Score: ");
tempStr = Console.ReadLine();
score = Convert.ToInt32(tempStr);
var tempStudent = new Student(name, num, score);
studentList.Add(tempStudent);
}
#region Serialize
try
{
if (File.Exists(@"StudentData.txt"))
{
File.Copy("StudentData.txt", "StudentData_tb.txt");
Console.WriteLine("StudentData.txt already exists, copied it to StudentData_tb.txt");
}
FileStream fs = new FileStream("StudentData.txt", FileMode.Create);
BinaryFormatter bf = new BinaryFormatter();
bf.Serialize(fs, studentList);
fs.Close();
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
Console.WriteLine("Serialize successful!");
#endregion
#region Deserialize
try
{
FileStream fs = new FileStream("StudentData.txt", FileMode.Open, FileAccess.Read);
BinaryFormatter bf = new BinaryFormatter();
ArrayList desList = (ArrayList) bf.Deserialize(fs);
foreach (Student s in desList)
{
Console.WriteLine(s.Name + " " + s.Num + " " + s.Score);
}
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
#endregion
Console.ReadKey();
}
}
}