For this example, let's say I want to create a program that keeps track of all the cars my friends own. I'm going to create two objects to achieve this:
Car
and Owner
. The Car
object will store the make, model, and year of the car. The Owner
object will save some information about who owns the car. Each Car
object will hold a reference to an Owner
object.//information about the car
public class Car
{
private string make;
private string model;
private int year;
private Owner owner;
public Car()
{
}
}
//information about the car's owner
public class Owner
{
private string firstName;
private string lastName;
public Owner()
{
}
}
public class Car
{
private string make;
private string model;
private int year;
private Owner owner;
public Car()
{
}
}
//information about the car's owner
public class Owner
{
private string firstName;
private string lastName;
public Owner()
{
}
}
Since most of us have more than one friend, we're going to need to create a
List
of Car
objects.List<Car> cars = new List<Car>();
Now that we have our objects created, we're almost ready to serialize them. When I save data to files, I like to create an object specifically to hold all the things I want to serialize.
public class ObjectToSerialize
{
private List<Car> cars;
public List<Car> Cars
{
get { return this.cars; }
set { this.cars = value; }
}
public ObjectToSerialize()
{
}
}
{
private List<Car> cars;
public List<Car> Cars
{
get { return this.cars; }
set { this.cars = value; }
}
public ObjectToSerialize()
{
}
}
This class holds a reference to every object we'll want to serialize. In this case, the only thing we want to save is the list of cars. Now lets create the functions that will perform the serialization and deserialization of our object. I usually create a
Serializer
class to control the writing and reading to and from files.using System.IO;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
public class Serializer
{
public Serializer()
{
}
public void SerializeObject(string filename, ObjectToSerialize objectToSerialize)
{
Stream stream = File.Open(filename, FileMode.Create);
BinaryFormatter bFormatter = new BinaryFormatter();
bFormatter.Serialize(stream, objectToSerialize);
stream.Close();
}
public ObjectToSerialize DeSerializeObject(string filename)
{
ObjectToSerialize objectToSerialize;
Stream stream = File.Open(filename, FileMode.Open);
BinaryFormatter bFormatter = new BinaryFormatter();
objectToSerialize = (ObjectToSerialize)bFormatter.Deserialize(stream);
stream.Close();
return objectToSerialize;
}
}
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
public class Serializer
{
public Serializer()
{
}
public void SerializeObject(string filename, ObjectToSerialize objectToSerialize)
{
Stream stream = File.Open(filename, FileMode.Create);
BinaryFormatter bFormatter = new BinaryFormatter();
bFormatter.Serialize(stream, objectToSerialize);
stream.Close();
}
public ObjectToSerialize DeSerializeObject(string filename)
{
ObjectToSerialize objectToSerialize;
Stream stream = File.Open(filename, FileMode.Open);
BinaryFormatter bFormatter = new BinaryFormatter();
objectToSerialize = (ObjectToSerialize)bFormatter.Deserialize(stream);
stream.Close();
return objectToSerialize;
}
}
As you can see, the actual code required to serialize an object is relatively small and simple. At this point, however, the code will not build. Before the
Serialize
function can be called on ObjectToSerialize
we must include the Serializable attribute and it must implement the ISerializable interface.using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
[Serializable()]
public class ObjectToSerialize : ISerializable
{
private List<Car> cars;
public List<Car> Cars
{
get { return this.cars; }
set { this.cars = value; }
}
public ObjectToSerialize()
{
}
public ObjectToSerialize(SerializationInfo info, StreamingContext ctxt)
{
this.cars = (List<Car>)info.GetValue("Cars", typeof(List<Car>));
}
public void GetObjectData(SerializationInfo info, StreamingContext ctxt)
{
info.AddValue("Cars", this.cars);
}
}
using System.Runtime.Serialization.Formatters.Binary;
[Serializable()]
public class ObjectToSerialize : ISerializable
{
private List<Car> cars;
public List<Car> Cars
{
get { return this.cars; }
set { this.cars = value; }
}
public ObjectToSerialize()
{
}
public ObjectToSerialize(SerializationInfo info, StreamingContext ctxt)
{
this.cars = (List<Car>)info.GetValue("Cars", typeof(List<Car>));
}
public void GetObjectData(SerializationInfo info, StreamingContext ctxt)
{
info.AddValue("Cars", this.cars);
}
}
As part of the ISerializable interface, the class must include another constructor for deserializing the object and a function
GetObjectData
which describes how to serialize the object. Since the Car and Owner objects are also being serialized, they will also need to implement these functions.[Serializable()]
public class Car : ISerializable
{
private string make;
private string model;
private int year;
private Owner owner;
public Car()
{
}
public Car(SerializationInfo info, StreamingContext ctxt)
{
this.make = (string)info.GetValue("Make", typeof(string));
this.model = (string)info.GetValue("Model",typeof(string));
this.year = (string)info.GetValue("Year", typeof(int));
this.owner = (Owner)info.GetValue("Owner", typeof(Owner));
}
public void GetObjectData(SerializationInfo info, StreamingContext ctxt)
{
info.AddValue("Make", this.make);
info.AddValue("Model", this.model);
info.AddValue("Make", this.year);
info.AddValue("Owner", this.owner);
}
}
[Serializable()]
public class Owner : ISerializable
{
private string firstName;
private string lastName;
public Owner()
{
}
public Owner(SerializationInfo info, StreamingContext ctxt)
{
this.firstName = (string)info.GetValue("FirstName", typeof(string));
this.lastName = (string)info.GetValue("LastName", typeof(string));
}
public void GetObjectData(SerializationInfo info, StreamingContext ctxt)
{
info.AddValue("FirstName", this.firstName);
info.AddValue("LastName", this.lastName);
}
}
public class Car : ISerializable
{
private string make;
private string model;
private int year;
private Owner owner;
public Car()
{
}
public Car(SerializationInfo info, StreamingContext ctxt)
{
this.make = (string)info.GetValue("Make", typeof(string));
this.model = (string)info.GetValue("Model",typeof(string));
this.year = (string)info.GetValue("Year", typeof(int));
this.owner = (Owner)info.GetValue("Owner", typeof(Owner));
}
public void GetObjectData(SerializationInfo info, StreamingContext ctxt)
{
info.AddValue("Make", this.make);
info.AddValue("Model", this.model);
info.AddValue("Make", this.year);
info.AddValue("Owner", this.owner);
}
}
[Serializable()]
public class Owner : ISerializable
{
private string firstName;
private string lastName;
public Owner()
{
}
public Owner(SerializationInfo info, StreamingContext ctxt)
{
this.firstName = (string)info.GetValue("FirstName", typeof(string));
this.lastName = (string)info.GetValue("LastName", typeof(string));
}
public void GetObjectData(SerializationInfo info, StreamingContext ctxt)
{
info.AddValue("FirstName", this.firstName);
info.AddValue("LastName", this.lastName);
}
}
Now, to save the list of objects to a file, all that needs to be done is to call the
Serialize
and DeSerialize
functions of the Serializer class.List<Car> cars = new List<Car>();
//save the car list to a file
ObjectToSerialize objectToSerialize = new ObjectToSerialize();
objectToSerialize.Cars = cars;
Serializer serializer = new Serializer()
serializer.SerializeObject("outputFile.txt", objectToSerialize);
//the car list has been saved to outputFile.txt
//read the file back from outputFile.txt
objectToSerialize = serializer.DeSerializeObject("outputFile.txt");
cars = objectToSerialize.Cars;
//save the car list to a file
ObjectToSerialize objectToSerialize = new ObjectToSerialize();
objectToSerialize.Cars = cars;
Serializer serializer = new Serializer()
serializer.SerializeObject("outputFile.txt", objectToSerialize);
//the car list has been saved to outputFile.txt
//read the file back from outputFile.txt
objectToSerialize = serializer.DeSerializeObject("outputFile.txt");
cars = objectToSerialize.Cars;
That is all that's required to save and load custom C# objects to a binary file. Just like any file, it is possible for your files to become corrupted. Because of this, it is probably a good idea to add some error handling whenever output from the file is being cast to an object.
ref : http://www.switchonthecode.com/tutorials/csharp-tutorial-serialize-objects-to-a-file
0 nhận xét :
Đăng nhận xét