You can use the BinaryFormatter. It's a good solution for wanting a small file, but only you know if it's the best solution for your domain. I don't think you can read one record at a time, though.
The only example code I have at this time is for a DataSet. These extension methods will (de)serialize a custom DataSet, which, if I recall correctly, was the easiest way to have a type that can use the BinaryFormatter.
public static TDataSet LoadBinary<TDataSet>(Stream stream) where TDataSet : DataSet
{
var formatter = new BinaryFormatter();
return (TDataSet)formatter.Deserialize(stream);
}
public static void WriteBinary<TDataSet>(this TDataSet dataSet, Stream stream) where TDataSet : DataSet
{
dataSet.RemotingFormat = SerializationFormat.Binary;
var formatter = new BinaryFormatter();
formatter.Serialize(stream, dataSet);
}
You might also take a look at the DataContractSerializer, which is .NET's new 'standard' way of dealing with serialization (according to C# 4.0 In A Nutshell, Albahari & Albahari). In that case, you'll also want to read Best Practices: Data Contract Versioning. Below are examples of how to (de)serialize in XML and JSON, even though they wouldn't be directly applicable to your situation (since you wanted small files). But you could compress the files.
/// <summary>
/// Converts this instance to XML using the <see cref="DataContractSerializer"/>.
/// </summary>
/// <typeparam name="TSerializable">
/// A type that is serializable using the <see cref="DataContractSerializer"/>.
/// </typeparam>
/// <param name="value">
/// The object to be serialized to XML.
/// </param>
/// <returns>
/// Formatted XML representing this instance. Does not include the XML declaration.
/// </returns>
public static string ToXml<TSerializable>(this TSerializable value)
{
var serializer = new DataContractSerializer(typeof(TSerializable));
var output = new StringWriter();
using (var writer = new XmlTextWriter(output) { Formatting = Formatting.Indented })
{
serializer.WriteObject(writer, value);
}
return output.GetStringBuilder().ToString();
}
/// <summary>
/// Converts this instance to XML using the <see cref="DataContractSerializer"/> and writes it to the specified file.
/// </summary>
/// <typeparam name="TSerializable">
/// A type that is serializable using the <see cref="DataContractSerializer"/>.
/// </typeparam>
/// <param name="value">
/// The object to be serialized to XML.
/// </param>
/// <param name="filePath">Path of the file to write to.</param>
public static void WriteXml<TSerializable>(this TSerializable value, string filePath)
{
var serializer = new DataContractSerializer(typeof(TSerializable));
using (var writer = XmlWriter.Create(filePath, new XmlWriterSettings { Indent = true }))
{
serializer.WriteObject(writer, value);
}
}
/// <summary>
/// Creates from an instance of the specified class from XML.
/// </summary>
/// <typeparam name="TSerializable">The type of the serializable object.</typeparam>
/// <param name="xml">The XML representation of the instance.</param>
/// <returns>An instance created from the XML input.</returns>
public static TSerializable CreateFromXml<TSerializable>(string xml)
{
var serializer = new DataContractSerializer(typeof(TSerializable));
using (var stringReader = new StringReader(xml))
using (var reader = XmlReader.Create(stringReader))
{
return (TSerializable)serializer.ReadObject(reader);
}
}
/// <summary>
/// Creates from an instance of the specified class from the specified XML file.
/// </summary>
/// <param name="filePath">
/// Path to the XML file.
/// </param>
/// <typeparam name="TSerializable">
/// The type of the serializable object.
/// </typeparam>
/// <returns>
/// An instance created from the XML input.
/// </returns>
public static TSerializable CreateFromXmlFile<TSerializable>(string filePath)
{
var serializer = new DataContractSerializer(typeof(TSerializable));
using (var reader = XmlReader.Create(filePath))
{
return (TSerializable)serializer.ReadObject(reader);
}
}
public static T LoadJson<T>(Stream stream) where T : class
{
var serializer = new DataContractJsonSerializer(typeof(T));
object readObject = serializer.ReadObject(stream);
return (T)readObject;
}
public static void WriteJson<T>(this T value, Stream stream) where T : class
{
var serializer = new DataContractJsonSerializer(typeof(T));
serializer.WriteObject(stream, value);
}