如何将可序列化对象保存/恢复到文件?

Ton*_*Nam 88 c# serialization stream

我有一个对象列表,我需要将其保存在我的计算机中.我已经阅读了一些论坛,我知道该对象必须是Serializable.但如果我能得到一个例子,那就太好了.例如,如果我有以下内容:

[Serializable]
public class SomeClass
{
     public string someProperty { get; set; }
}

SomeClass object1 = new SomeClass { someProperty = "someString" };
Run Code Online (Sandbox Code Playgroud)

但是,如何object1在我的计算机中存储某个地方以后再检索?

Ale*_*dez 133

您可以使用以下内容:

    /// <summary>
    /// Serializes an object.
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="serializableObject"></param>
    /// <param name="fileName"></param>
    public void SerializeObject<T>(T serializableObject, string fileName)
    {
        if (serializableObject == null) { return; }

        try
        {
            XmlDocument xmlDocument = new XmlDocument();
            XmlSerializer serializer = new XmlSerializer(serializableObject.GetType());
            using (MemoryStream stream = new MemoryStream())
            {
                serializer.Serialize(stream, serializableObject);
                stream.Position = 0;
                xmlDocument.Load(stream);
                xmlDocument.Save(fileName);
            }
        }
        catch (Exception ex)
        {
            //Log exception here
        }
    }


    /// <summary>
    /// Deserializes an xml file into an object list
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="fileName"></param>
    /// <returns></returns>
    public T DeSerializeObject<T>(string fileName)
    {
        if (string.IsNullOrEmpty(fileName)) { return default(T); }

        T objectOut = default(T);

        try
        {
            XmlDocument xmlDocument = new XmlDocument();
            xmlDocument.Load(fileName);
            string xmlString = xmlDocument.OuterXml;

            using (StringReader read = new StringReader(xmlString))
            {
                Type outType = typeof(T);

                XmlSerializer serializer = new XmlSerializer(outType);
                using (XmlReader reader = new XmlTextReader(read))
                {
                    objectOut = (T)serializer.Deserialize(reader);
                }
            }
        }
        catch (Exception ex)
        {
            //Log exception here
        }

        return objectOut;
    }
Run Code Online (Sandbox Code Playgroud)

  • 无需在使用块内的读取器上调用close方法.Dispose()是隐式的,即使在显式Close()之前在块内引发异常也会发生.非常有用的代码块. (3认同)
  • 如何使用此功能保存对象列表我用过它,但它仅保存列表中的最后一个对象 (2认同)

dea*_*dog 126

我刚写了一篇关于将对象数据保存到Binary,XML或Json的博客文章.你必须用[Serializable]属性装饰你的类是正确的,但前提是你使用的是二进制序列化.您可能更喜欢使用XML或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 binary 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 binary 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 binary 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 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);
    }
}
Run Code Online (Sandbox Code Playgroud)

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();
    }
}
Run Code Online (Sandbox Code Playgroud)

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();
    }
}
Run Code Online (Sandbox Code Playgroud)

// Write the contents of the variable someClass to a file.
WriteToBinaryFile<SomeClass>("C:\someClass.txt", object1);

// Read the file contents back into a variable.
SomeClass object1= ReadFromBinaryFile<SomeClass>("C:\someClass.txt");
Run Code Online (Sandbox Code Playgroud)

  • 我喜欢你的二进制序列化代码.但是在WriteToBinaryFile上你为什么要附加到文件?在所有情况下,您似乎都想创建一个新文件.否则,反序列化会有一大堆额外的信息. (2认同)
  • @publicwireless 是的,您可能是对的。我当时并没有想太多;我只是想让 3 个函数的签名匹配:P (2认同)

All*_*enG 30

您需要序列化为某些内容:即选择二进制文件或xml(对于默认序列化程序)或编写自定义序列化代码以序列化为其他文本格式.

一旦你选择了它,你的序列化将(通常)调用写入某种文件的Stream.

因此,使用您的代码,如果我使用XML序列化:

var path = @"C:\Test\myserializationtest.xml";
using(FileStream fs = new FileStream(path, FileMode.Create))
{
    XmlSerializer xSer = new XmlSerializer(typeof(SomeClass));

    xSer.Serialize(fs, serializableObject);
}
Run Code Online (Sandbox Code Playgroud)

然后,反序列化:

using(FileStream fs = new FileStream(path, FileMode.Open)) //double check that...
{
    XmlSerializer _xSer = new XmlSerializer(typeof(SomeClass));

    var myObject = _xSer.Deserialize(fs);
}
Run Code Online (Sandbox Code Playgroud)

注意:此代码尚未编译,更不用说运行 - 可能存在一些错误.此外,这假定完全开箱即用的序列化/反序列化.如果您需要自定义行为,则需要执行其他工作.


Emd*_*won 10

1.从文件恢复对象

这里, 您可以通过两种方式从文件反序列化对象.

解决方案-1:将文件读入字符串并将JSON反序列化为类型

string json = File.ReadAllText(@"c:\myObj.json");
MyObject myObj = JsonConvert.DeserializeObject<MyObject>(json);
Run Code Online (Sandbox Code Playgroud)

解决方案-2:直接从文件反序列化JSON

using (StreamReader file = File.OpenText(@"c:\myObj.json"))
{
    JsonSerializer serializer = new JsonSerializer();
    MyObject myObj2 = (MyObject)serializer.Deserialize(file, typeof(MyObject));
}
Run Code Online (Sandbox Code Playgroud)

2.将对象保存到文件

这里,您可以以两种方式将对象序列化为文件.

解决方案-1:将JSON序列化为字符串,然后将字符串写入文件

string json = JsonConvert.SerializeObject(myObj);
File.WriteAllText(@"c:\myObj.json", json);
Run Code Online (Sandbox Code Playgroud)

解决方案-2:将JSON直接序列化到文件

using (StreamWriter file = File.CreateText(@"c:\myObj.json"))
{
    JsonSerializer serializer = new JsonSerializer();
    serializer.Serialize(file, myObj);
}
Run Code Online (Sandbox Code Playgroud)

3.额外

您可以通过以下命令从NuGet下载Newtonsoft.Json

Install-Package Newtonsoft.Json
Run Code Online (Sandbox Code Playgroud)


oza*_*mut 5

您可以使用 Newtonsoft 库中的 JsonConvert。序列化对象并以 json 格式写入文件:

File.WriteAllText(filePath, JsonConvert.SerializeObject(obj));
Run Code Online (Sandbox Code Playgroud)

并将其反序列化回对象:

var obj = JsonConvert.DeserializeObject<ObjType>(File.ReadAllText(filePath));
Run Code Online (Sandbox Code Playgroud)