C# Serialize List (Write to File With BinaryFormatter)

This C# tutorial serializes a List with the Serializable attribute. It uses BinaryFormatter.

List, serialize.

A List can be serialized to the disk. We want to serialize (to a file) a List of objects. The next time the program runs, we get this List straight from the disk. We see an example of BinaryFormatter and its Serialize methods.List


This is the first part of the code example. We see a class in C# code, which you will want to put in a file called Lizard.cs. But you can also just put it in the same file. It adds several important namespaces in the using-statements.
C# program that describes serializable type using System; using System.Collections.Generic; using System.IO; using System.Runtime.Serialization.Formatters.Binary; [Serializable()] public class Lizard { public string Type { get; set; } public int Number { get; set; } public bool Healthy { get; set; } public Lizard(string t, int n, bool h) { Type = t; Number = n; Healthy = h; } }

We see

a class called Lizard, and it has three automatic properties. These store values and also are properties so are publicly accessible. The first constructor in the example accepts three values, a string, an int and a bool.

Note: The Serializable attribute is specified right before the class definition.

Note 2: It tells the .NET Framework that the properties on this class can be written to a file and read back from.

Example 2.

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.
C# program that serializes the type 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:

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. It is fun to test the program in a console project.

When you press

"s", a new List of Lizard objects is created. Five different Lizard objects are instantiated. Next, we wrap the file IO code in a try-catch block. This is important because file IO frequently throws.

And: The Stream is wrapped in a using block. The File.Open call attempts to open the new file for writing.


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.


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>.

Note: The Deserialize method, which accepts the Stream as a parameter, is slow but also powerful.

Finally: We write the List of Lizards it has read in from the file to the screen in a foreach-loop.



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.Property


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


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.
Dot Net Perls
© 2007-2019 Sam Allen. All rights reserved. Written by Sam Allen,