如何快速保存/加载类实例到文件

时间:2010-11-24 12:39:40

标签: c# .net file serialization

我的应用程序中有几个类/结构集合。

该类只是一个带字段

的类
class A
{
  public int somevalue;
  public string someothervalue
}

我的收藏

List<A> _myList;

我需要能够保存_myList并加载。我只想将所有类字段保存到文件和加载。我不想花时间写自己的保存/加载。 .NET中是否有任何工具可以帮助我。我不关心文件格式。

7 个答案:

答案 0 :(得分:14)

我刚写了a blog post on saving an object's data to Binary, XML, or Json;将对象或对象列表写入文件。以下是以各种格式执行此操作的功能。有关详细信息,请参阅我的博文。

二进制

/// <summary>
/// Writes the given object instance to a binary file.
/// <para>Object type (and all child types) must be decorated with the [Serializable] attribute.</para>
/// <para>To prevent a variable from being serialized, decorate it with the [NonSerialized] attribute; cannot be applied to properties.</para>
/// </summary>
/// <typeparam name="T">The type of object being written to the XML file.</typeparam>
/// <param name="filePath">The file path to write the object instance to.</param>
/// <param name="objectToWrite">The object instance to write to the XML file.</param>
/// <param name="append">If false the file will be overwritten if it already exists. If true the contents will be appended to the file.</param>
public static void WriteToBinaryFile<T>(string filePath, T objectToWrite, bool append = false)
{
    using (Stream stream = File.Open(filePath, append ? FileMode.Append : FileMode.Create))
    {
        var binaryFormatter = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
        binaryFormatter.Serialize(stream, objectToWrite);
    }
}

/// <summary>
/// Reads an object instance from a binary file.
/// </summary>
/// <typeparam name="T">The type of object to read from the XML.</typeparam>
/// <param name="filePath">The file path to read the object instance from.</param>
/// <returns>Returns a new instance of the object read from the binary file.</returns>
public static T ReadFromBinaryFile<T>(string filePath)
{
    using (Stream stream = File.Open(filePath, FileMode.Open))
    {
        var binaryFormatter = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
        return (T)binaryFormatter.Deserialize(stream);
    }
}

XML

要求System.Xml程序集包含在项目中。

/// <summary>
/// Writes the given object instance to an XML file.
/// <para>Only Public properties and variables will be written to the file. These can be any type though, even other classes.</para>
/// <para>If there are public properties/variables that you do not want written to the file, decorate them with the [XmlIgnore] attribute.</para>
/// <para>Object type must have a parameterless constructor.</para>
/// </summary>
/// <typeparam name="T">The type of object being written to the file.</typeparam>
/// <param name="filePath">The file path to write the object instance to.</param>
/// <param name="objectToWrite">The object instance to write to the file.</param>
/// <param name="append">If false the file will be overwritten if it already exists. If true the contents will be appended to the file.</param>
public static void WriteToXmlFile<T>(string filePath, T objectToWrite, bool append = false) where T : new()
{
    TextWriter writer = null;
    try
    {
        var serializer = new XmlSerializer(typeof(T));
        writer = new StreamWriter(filePath, append);
        serializer.Serialize(writer, objectToWrite);
    }
    finally
    {
        if (writer != null)
            writer.Close();
    }
}

/// <summary>
/// Reads an object instance from an XML file.
/// <para>Object type must have a parameterless constructor.</para>
/// </summary>
/// <typeparam name="T">The type of object to read from the file.</typeparam>
/// <param name="filePath">The file path to read the object instance from.</param>
/// <returns>Returns a new instance of the object read from the XML file.</returns>
public static T ReadFromXmlFile<T>(string filePath) where T : new()
{
    TextReader reader = null;
    try
    {
        var serializer = new XmlSerializer(typeof(T));
        reader = new StreamReader(filePath);
        return (T)serializer.Deserialize(reader);
    }
    finally
    {
        if (reader != null)
            reader.Close();
    }
}

的Json

您必须包含对Newtonsoft.Json程序集的引用,该程序集可以从Json.NET NuGet Package获取。

/// <summary>
/// Writes the given object instance to a Json file.
/// <para>Object type must have a parameterless constructor.</para>
/// <para>Only Public properties and variables will be written to the file. These can be any type though, even other classes.</para>
/// <para>If there are public properties/variables that you do not want written to the file, decorate them with the [JsonIgnore] attribute.</para>
/// </summary>
/// <typeparam name="T">The type of object being written to the file.</typeparam>
/// <param name="filePath">The file path to write the object instance to.</param>
/// <param name="objectToWrite">The object instance to write to the file.</param>
/// <param name="append">If false the file will be overwritten if it already exists. If true the contents will be appended to the file.</param>
public static void WriteToJsonFile<T>(string filePath, T objectToWrite, bool append = false) where T : new()
{
    TextWriter writer = null;
    try
    {
        var contentsToWriteToFile = JsonConvert.SerializeObject(objectToWrite);
        writer = new StreamWriter(filePath, append);
        writer.Write(contentsToWriteToFile);
    }
    finally
    {
        if (writer != null)
            writer.Close();
    }
}

/// <summary>
/// Reads an object instance from an Json file.
/// <para>Object type must have a parameterless constructor.</para>
/// </summary>
/// <typeparam name="T">The type of object to read from the file.</typeparam>
/// <param name="filePath">The file path to read the object instance from.</param>
/// <returns>Returns a new instance of the object read from the Json file.</returns>
public static T ReadFromJsonFile<T>(string filePath) where T : new()
{
    TextReader reader = null;
    try
    {
        reader = new StreamReader(filePath);
        var fileContents = reader.ReadToEnd();
        return JsonConvert.DeserializeObject<T>(fileContents);
    }
    finally
    {
        if (reader != null)
            reader.Close();
    }
}

实施例

// Write the list of objects to a file.
WriteToXmlFile<List<A>>("C:\myObjects.txt", _myList);

// Read the list of objects from the file back into a variable.
List<A> _myList = ReadFromXmlFile<List<A>>("C:\myObjects.txt");

答案 1 :(得分:9)

XMLSerializer并不难使用。只要你的物体不是很大,它就会很快。我在一些应用程序中序列化了一些巨大的对象。它需要永远,结果文件几乎100兆,但如果我需要调整一些东西,它们是可编辑的。另外,如果我向对象添加字段也没关系。旧版本对象的序列化文件仍然正确反序列化。我在一个单独的线程上进行序列化,所以在我的情况下需要多长时间。需要注意的是,您的A类必须具有XMLSerialziation的构造函数才能工作。

这是我用来序列化/反序列化的一些工作代码,错误处理被撕掉以便于阅读......

private List<A> Load()
{
    string file = "filepath";
    List<A> listofa = new List<A>();
    XmlSerializer formatter = new XmlSerializer(A.GetType());
    FileStream aFile = new FileStream(file, FileMode.Open);
    byte[] buffer = new byte[aFile.Length];
    aFile.Read(buffer, 0, (int)aFile.Length);
    MemoryStream stream = new MemoryStream(buffer);
    return (List<A>)formatter.Deserialize(stream);
}


private void Save(List<A> listofa)
{
    string path = "filepath";
    FileStream outFile = File.Create(path);
    XmlSerializer formatter = new XmlSerializer(A.GetType());
    formatter.Serialize(outFile, listofa);
}

答案 2 :(得分:2)

有许多序列化器:

.net框架的一部分

  • XmlSerializer(标准化格式,慢速和详细)
  • BinarySerializer(专有格式,中速,支持循环图,序列化字段而不是属性=&gt; 恼人的版本控制

第三方:

  • Json-Serializers(标准化格式,基于文本,短于xml)
  • ProtoBuf-Serializers(标准格式,二进制,非常快)

如果文件可能是二进制文件,我可能会使用ProtoBuf Serializer;如果它需要是纯文本的话,我可能会使用json序列化程序。

答案 3 :(得分:1)

我通常使用XML Serilizer,快速,易于实现并以可读的方式保持对象,你可以看到一个不错的example

如果您需要更有效的更大规模的解决方案,则可以使用二进制序列化。 (例如,如果要通过网络传输序列化。)

编辑:为了更好地控制您序列化的元素,请查看此example

答案 4 :(得分:1)

您可以使用XML序列化程序或二进制序列化程序序列化List<>,并将序列化列表保存到文件中。

稍后,您可以阅读此文件内容并检索原始列表。

创建您要为其创建列表[Serializable]

的类型

答案 5 :(得分:1)

老话题,但我修改了Tim Coker上面的答案,利用using块来正确处理流对象,并且一次只保存一个类实例:

public static T Load<T>(string FileSpec) {
    XmlSerializer formatter = new XmlSerializer(typeof(T));

    using (FileStream aFile = new FileStream(FileSpec, FileMode.Open)) {
        byte[] buffer = new byte[aFile.Length];
        aFile.Read(buffer, 0, (int)aFile.Length);

        using (MemoryStream stream = new MemoryStream(buffer)) {
            return (T)formatter.Deserialize(stream);
        }
    }
}

public static void Save<T>(T ToSerialize, string FileSpec) {
    Directory.CreateDirectory(FileSpec.Substring(0, FileSpec.LastIndexOf('\\')));
    FileStream outFile = File.Create(FileSpec);
    XmlSerializer formatter = new XmlSerializer(typeof(T));

    formatter.Serialize(outFile, ToSerialize);
}

答案 6 :(得分:0)

我们可以通过以下方式之一从文件中保存和加载对象。

BinarySerialization,XmlSerialization,JsonSerialization

public enum Serialization
{
    BinarySerialization = 1,
    XmlSerialization = 2,
    JsonSerialization = 3,
}
public static void SaveObjectToFile<T>(Serialization serialization, string filePath ,T objectToSave)
{
    Directory.CreateDirectory(filePath.Substring(0, filePath.LastIndexOf('\\')));
     using (StreamWriter writer = new StreamWriter(filePath))
    {
        switch (serialization)
        {
            case Serialization.XmlSerialization: //Object type must have a parameterless constructor
                XmlSerializer formatter = new XmlSerializer(typeof(T));
                //Use the [XmlIgnore] attribute to exclude a public property or variable from being written to the file.(in XML Serialization only)
                formatter.Serialize(writer, objectToSave);
                break;
            case Serialization.JsonSerialization: //Object type must have a parameterless constructor
                var contentsToWriteToFile = Newtonsoft.Json.JsonConvert.SerializeObject(objectToSave);
                //[JsonIgnore] attribute to exclude a public property or variable from being written to the file.
                writer.Write(contentsToWriteToFile);
                break;
            case Serialization.BinarySerialization: 
                var binaryFormatter = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
                //decorate class (and all classes that it contains) with a [Serializable] attribute.Use the [NonSerialized] attribute to exclude a variable from being written to the file;
                binaryFormatter.Serialize(writer.BaseStream, objectToSave);
                break;
        }
    }
}
public static T LoadObjectToFile<T>(Serialization serialization, string filePath)
{
    using (StreamReader reader = new StreamReader(filePath))
    {
        switch (serialization)
        {
            case Serialization.XmlSerialization:
                XmlSerializer formatter = new XmlSerializer(typeof(T));
                return (T)formatter.Deserialize(reader);
            case Serialization.JsonSerialization:
                var fileContents = reader.ReadToEnd();
                return Newtonsoft.Json.JsonConvert.DeserializeObject<T>(fileContents);
            case Serialization.BinarySerialization:
                var binaryFormatter = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
                return (T)binaryFormatter.Deserialize(reader.BaseStream);
            default:
                 throw new System.ArgumentOutOfRangeException("Serialization = "+Convert.ToString(serialization));
        }
    }
}