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));