Как сохранить/восстановить сериализуемый объект в/из файла?
У меня есть список объектов, и мне нужно сохранить это где-то на моем компьютере. Я прочитал несколько форумов, и я знаю, что объект должен быть Serializable
. Но было бы неплохо, если бы я смог привести пример. Например, если у меня есть следующее:
[Serializable]
public class SomeClass
{
public string someProperty { get; set; }
}
SomeClass object1 = new SomeClass { someProperty = "someString" };
Но как я могу хранить object1
где-то на своем компьютере и позже извлекать?
Ответы
Ответ 1
Вы можете использовать следующее:
/// <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;
}
Ответ 2
Я просто написал сообщение в блоге о сохранении данных объекта в 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);
}
}
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, которая может быть получена из пакета NuGet Json.NET.
/// <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 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");
Ответ 3
Вам нужно будет сериализоваться на что-то: выбрать бинарный или 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);
}
ПРИМЕЧАНИЕ. Этот код не был скомпилирован, не говоря уже о запуске - могут быть некоторые ошибки. Кроме того, это предполагает полную сериализацию/десериализацию. Если вам нужно индивидуальное поведение, вам нужно будет выполнить дополнительную работу.
Ответ 4
1. Восстановить объект из файла
Из Здесь вы можете десериализовать объект из файла двумя способами.
Решение-1: чтение файла в строку и десериализация JSON для типа
string json = File.ReadAllText(@"c:\myObj.json");
MyObject myObj = JsonConvert.DeserializeObject<MyObject>(json);
Решение-2: десериализовать JSON непосредственно из файла
using (StreamReader file = File.OpenText(@"c:\myObj.json"))
{
JsonSerializer serializer = new JsonSerializer();
MyObject myObj2 = (MyObject)serializer.Deserialize(file, typeof(MyObject));
}
2. Сохранить объект в файл
из здесь вы можете сериализовать объект в файл двумя способами.
Решение-1: Сериализовать JSON для строки, а затем записать строку в файл
string json = JsonConvert.SerializeObject(myObj);
File.WriteAllText(@"c:\myObj.json", json);
Решение-2: Сериализовать JSON непосредственно в файл
using (StreamWriter file = File.CreateText(@"c:\myObj.json"))
{
JsonSerializer serializer = new JsonSerializer();
serializer.Serialize(file, myObj);
}
3. Extra
Вы можете скачать Newtonsoft.Json из NuGet, выполнив команду
Install-Package Newtonsoft.Json
Ответ 5
** 1. Преобразуйте строку json в base64string и напишите или добавьте ее в двоичный файл. 2. Прочитайте base64string из двоичного файла и десериализуйте с помощью BsonReader. **
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);
}
}
}
Ответ 6
Вы можете использовать JsonConvert из библиотеки Newtonsoft. Для сериализации объекта и записи в файл в формате json:
File.WriteAllText(filePath, JsonConvert.SerializeObject(obj));
И десериализовать его обратно в объект:
var obj = JsonConvert.DeserializeObject<ObjType>(File.ReadAllText(filePath));