转自:http://www.dotnetperls.com/serialize-list
What is an easy way to persist or serialize a List instance to the disk? The problem is that you have a List of C# objects you want to write or serialize to a file. The next time your program runs, you want to get this List straight from the disk. Here we see a simple example of BinaryFormatter and its Serialize methods, in a complete, easy console application written in the C# language.
Tip: You can serialize with the [Serializable()] attribute in the C# language.
Example class
This is the first part of the code example here. Here we see a class in C# code, which you will want to put in a file called Lizard.cs. However, you can also just put it in the same file. It uses several important namespaces in the usings at the top.
Program that describes serializable type [C#] using System; using System.Collections.Generic; using System.IO; using System.Runtime.Serialization.Formatters.Binary; [Serializable()] public class Lizard { public string Type { get; set; } // String property for Lizard object public int Number { get; set; } // Number of lizards public bool Healthy { get; set; } // Whether lizard is healthy public Lizard(string t, int n, bool h) { Type = t; Number = n; Healthy = h; } }
Overview. This is a simple class called Lizard, and it has three automatic properties. These store values and also are properties so are publicly accessible.
Description of constructor. The first constructor in the example accepts three values, a string, an int and a bool. This is the regular constructor for use in the program.
Note on the [Serializable()] attribute. This attribute, which is specified right before the class definition, tells the .NET Framework that the properties on this class can be written to a file and read back from.
Example program
The second part of this tutorial is the Main method in your C# console program. It allows you to easily see how the data file is written to with BinaryFormatter, and how it is read from, deserialized.
Program that serializes the type [C#] using System; using System.Collections.Generic; using System.IO; using System.Runtime.Serialization.Formatters.Binary; // [Note: You can paste the Lizard class here] <-- class Program { static void Main() { while(true) { Console.WriteLine("s=serialize, r=read:"); switch (Console.ReadLine()) { case "s": var lizards1 = new List<Lizard>(); lizards1.Add(new Lizard("Thorny devil", 1, true)); lizards1.Add(new Lizard("Casquehead lizard", 0, false)); lizards1.Add(new Lizard("Green iguana", 4, true)); lizards1.Add(new Lizard("Blotched blue-tongue lizard", 0, false)); lizards1.Add(new Lizard("Gila monster", 1, false)); try { using (Stream stream = File.Open("data.bin", FileMode.Create)) { BinaryFormatter bin = new BinaryFormatter(); bin.Serialize(stream, lizards1); } } catch (IOException) { } break; case "r": try { using (Stream stream = File.Open("data.bin", FileMode.Open)) { BinaryFormatter bin = new BinaryFormatter(); var lizards2 = (List<Lizard>)bin.Deserialize(stream); foreach (Lizard lizard in lizards2) { Console.WriteLine("{0}, {1}, {2}", lizard.Type, lizard.Number, lizard.Healthy); } } } catch (IOException) { } break; } } } } Output s=serialize, r=read: s s=serialize, r=read: r Thorny devil, 1, True Casquehead lizard, 0, False Green iguana, 4, True Blotched blue-tongue lizard, 0, False Gila monster, 1, False s=serialize, r=read:
Description. This code is mostly a command line program that allows you to type "s" to write a List of classes to a file, and "r" to read in that same List.
List ExamplesHow it serializes the List of objects. When you press "s", a new List of Lizard objects is created. Five different Lizard objects are instantiated. Next, we wrap the file I/O code in a try/catch block. This is important because file I/O frequently throws. The Stream is wrapped in a using block. The File.Open call attempts to open the new file for writing.
File.Open ExamplesSerialization step with BinaryFormatter. The next task in the serialiation part is creating a new BinaryFormatter instance. We simply call the Serialize method on the BinaryFormatter instance. This Serialize method receives the stream you want to write to, and also the object itself.
How it deserializes the List from the file. The second part of the Main method above is where the file is deserialized. It again must use a Stream, which is wrapped in a using block for maximum efficiency and reliability. A new BinaryFormatter object is created, and it is used to get a new List<Lizard>. The Deserialize method, which accepts the Stream as a parameter, is slow and very powerful.
The objects are written to the screen. This console program next writes the List of Lizards it has read in from the file to the screen with a foreach loop. It would be ideal here to override the ToString method on Lizard.
Properties
It is important to use properties, which have the get and set keywords, in this sort of serialization code. Properties have special metadata in the compiled code, which allows the base class library to use sophisticated logic to populate them from a file.
Property ExamplesFile statistics
When the above code is run, it generates a 604-byte file for all the serialized data. When you open the file in Visual Studio, you can see the binary in hex values. The string names are all contained in raw format.
In this simple lizard example, using XML serialization might be best. This would generate a human-readable and editable data file, and would be more interoperable with web services.
XML TutorialsSummary
In this tutorial, we saw a powerful way to serialize binary data to a file. We took a List generic instance with five objects in it, and serialized it efficiently. We employed the using statement for optimal clarity of the Stream code.