C# 如何在文件中保存/恢复可序列化对象?

C# 如何在文件中保存/恢复可序列化对象?,c#,serialization,stream,C#,Serialization,Stream,我有一个对象列表,我需要把它保存在我电脑的某个地方。我读过一些论坛,我知道对象必须是可序列化的。但如果我能举个例子就好了。例如,如果我有以下内容: [Serializable] public class SomeClass { public string someProperty { get; set; } } SomeClass object1 = new SomeClass { someProperty = "someString" }; /// <summary

我有一个对象列表,我需要把它保存在我电脑的某个地方。我读过一些论坛,我知道对象必须是可序列化的。但如果我能举个例子就好了。例如,如果我有以下内容:

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

SomeClass object1 = new SomeClass { someProperty = "someString" };
    /// <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;
    }

但是如何将
object1
存储在计算机中的某个位置,然后在以后检索?

您可以使用以下方法:

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

SomeClass object1 = new SomeClass { someProperty = "someString" };
    /// <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;
    }
//
///序列化对象。
/// 
/// 
/// 
/// 
public void SerializeObject(T serializableObject,字符串文件名)
{
如果(serializableObject==null){return;}
尝试
{
XmlDocument XmlDocument=新的XmlDocument();
XmlSerializer serializer=新的XmlSerializer(serializableObject.GetType());
使用(MemoryStream stream=new MemoryStream())
{
serializer.Serialize(流,serializableObject);
流位置=0;
加载(流);
xmlDocument.Save(文件名);
}
}
捕获(例外情况除外)
{
//此处记录异常
}
}
/// 
///将xml文件反序列化为对象列表
/// 
/// 
/// 
/// 
公共T反序列化对象(字符串文件名)
{
if(string.IsNullOrEmpty(fileName)){返回默认值(T);}
T objectOut=默认值(T);
尝试
{
XmlDocument XmlDocument=新的XmlDocument();
加载(文件名);
字符串xmlString=xmlDocument.OuterXml;
使用(StringReader读取=新的StringReader(xmlString))
{
类型outType=类型of(T);
XmlSerializer serializer=新的XmlSerializer(outType);
使用(XmlReader=新的XmlTextReader(读取))
{
objectOut=(T)序列化程序。反序列化(读卡器);
}
}
}
捕获(例外情况除外)
{
//此处记录异常
}
退出;
}

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

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

因此,对于您的代码,如果我使用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);
}
然后,要反序列化:

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

    var myObject = _xSer.Deserialize(fs);
}
注意:此代码尚未编译,更不用说运行了-可能存在一些错误。此外,这假设完全是开箱即用的序列化/反序列化。如果您需要自定义行为,则需要做额外的工作。

我刚刚写道。正确的做法是必须使用[Serializable]属性装饰类,但前提是使用二进制序列化。您可能更喜欢使用XML或Json序列化。以下是各种格式的函数。有关更多详细信息,请参阅我的博客文章

二元的
//
///将给定对象实例写入二进制文件。
///对象类型(以及所有子类型)必须用[Serializable]属性修饰。
///要防止变量被序列化,请使用[NonSerialized]属性对其进行修饰;无法应用于属性。
/// 
///写入二进制文件的对象的类型。
///要将对象实例写入的文件路径。
///要写入二进制文件的对象实例。
///如果为false,则文件将被覆盖(如果它已存在)。如果为true,则内容将附加到文件中。
公共静态void WriteToBinaryFile(字符串文件路径,T objectToWrite,bool append=false)
{
使用(Stream-Stream=File.Open(filePath,append?FileMode.append:FileMode.Create))
{
var binaryFormatter=new System.Runtime.Serialization.Formatters.Binary.binaryFormatter();
序列化(流,objectToWrite);
}
}
/// 
///从二进制文件读取对象实例。
/// 
///要从二进制文件中读取的对象类型。
///从中读取对象实例的文件路径。
///返回从二进制文件读取的对象的新实例。
公共静态T ReadFromBinaryFile(字符串文件路径)
{
使用(Stream=File.Open(filePath,FileMode.Open))
{
var binaryFormatter=new System.Runtime.Serialization.Formatters.Binary.binaryFormatter();
返回(T)二进制格式化程序。反序列化(流);
}
}
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();
    }
}
//
///将给定对象实例写入XML文件。
///只有公共属性和变量才会写入文件。但是,它们可以是任何类型,甚至是其他类。
///如果存在不希望写入文件的公共属性/变量,请使用[XmlIgnore]属性对其进行修饰。
///对象类型必须具有无参数构造函数。
/// 
///正在写入文件的对象的类型。
///要将对象实例写入的文件路径。
///要写入文件的对象实例。
///如果为false,则文件将被覆盖(如果它已存在)。如果为true,则内容将附加到文件中。
公共静态void WriteToXmlFile(字符串文件路径,T objectToWrite,bool append=false),其中T:new()
{
TextWriter=null;
尝试
{
var serializer=newxmlserializer(typeof(T));
writer=newstreamwriter(文件路径,追加);
serializer.Serialize(writer,objectToWrite);
}
最后
{
if(writer!=null)
writer.Close();
}
}
/// 
///从XML文件读取对象实例。
///对象类型必须具有无参数构造函数。
/// 
///要从文件中读取的对象的类型。
///从中读取对象实例的文件路径。
///返回从XML文件读取的对象的新实例。
公共静态T ReadFromXmlFile(字符串文件路径),其中T:new()
{
TextReader=null;
尝试
{
弗吉尼亚州
// 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");
string json = File.ReadAllText(@"c:\myObj.json");
MyObject myObj = JsonConvert.DeserializeObject<MyObject>(json);
using (StreamReader file = File.OpenText(@"c:\myObj.json"))
{
    JsonSerializer serializer = new JsonSerializer();
    MyObject myObj2 = (MyObject)serializer.Deserialize(file, typeof(MyObject));
}
string json = JsonConvert.SerializeObject(myObj);
File.WriteAllText(@"c:\myObj.json", json);
using (StreamWriter file = File.CreateText(@"c:\myObj.json"))
{
    JsonSerializer serializer = new JsonSerializer();
    serializer.Serialize(file, myObj);
}
Install-Package Newtonsoft.Json
 public static class BinaryJson
{
    public static string SerializeToBase64String(this object obj)
    {
        JsonSerializer jsonSerializer = new JsonSerializer();
        MemoryStream objBsonMemoryStream = new MemoryStream();
        using (BsonWriter bsonWriterObject = new BsonWriter(objBsonMemoryStream))
        {
            jsonSerializer.Serialize(bsonWriterObject, obj);
            return Convert.ToBase64String(objBsonMemoryStream.ToArray());
        }           
        //return Encoding.ASCII.GetString(objBsonMemoryStream.ToArray());
    }
    public static T DeserializeToObject<T>(this string base64String)
    {
        byte[] data = Convert.FromBase64String(base64String);
        MemoryStream ms = new MemoryStream(data);
        using (BsonReader reader = new BsonReader(ms))
        {
            JsonSerializer serializer = new JsonSerializer();
            return serializer.Deserialize<T>(reader);
        }
    }
}
File.WriteAllText(filePath, JsonConvert.SerializeObject(obj));
var obj = JsonConvert.DeserializeObject<ObjType>(File.ReadAllText(filePath));