Как быстро сохранить / загрузить экземпляр класса в файл
у меня есть несколько коллекций классов/структур в моем приложении.
класс это просто класс с полями
class A
{
public int somevalue;
public string someothervalue
}
и моя коллекция
List<A> _myList;
мне нужно иметь возможность сохранять _myList и загружать. Я просто хочу сохранить все поля класса в файл и загрузить. Я не хочу тратить время на написание собственного сохранения/загрузки. Есть любые инструменты .Net, чтобы помочь мне. Меня не волнует формат файла.
6 ответов
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);
}
Я только что написал сообщение в блоге о сохранении данных объекта в двоичном формате, 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 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
требует система.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.
/// <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");
существует много сериализаторов:
часть .net framework
- XmlSerializer (стандартизированный формат, медленный и подробный)
- BinarySerializer (собственный формат, средняя скорость,поддерживает циклические графы, сериализует поля вместо properties => раздражает версий)
3-й участник:
- JSON-сериализаторы (стандартизированный формат, текстовый, короче xml)
- ProtoBuf-сериализаторы (стандартизированный формат, двоичный, очень быстрый)
Я бы, вероятно, использовал сериализатор ProtoBuf, если файл может быть двоичным, и сериализатор json, если он должен быть текстовым.
Вы можете сериализовать свой List<>
использование XML-сериализатора или двоичного сериализатора и сохранение сериализованного списка в файл.
позже вы можете прочитать содержимое этого файла и получить исходный список.
сделать свой тип, для которого вы создаете список [Serializable]
Я обычно использую XML-Серилизатор, быстро, легко реализовать и сохранить объекты в удобочитаемом виде, вы можете увидеть хороший пример.
вы можете использовать двоичную сериализацию, если хотите более эффективное обфустированное решение. (например, если вы хотите передать сериализацию по сети.)
EDIT: чтобы получить больше контроля над элементами, которые вы сериализуете, взгляните на это пример
старая тема, но я изменил ответ Тима Кокера выше, чтобы использовать блоки using для правильного удаления объектов stream и сохранения только одного экземпляра класса за раз:
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);
}