How to quickly save/load class instance to file

后端 未结 7 1428
终归单人心
终归单人心 2020-12-09 05:33

I have several collections of classes/structs in my app.

The class is just a class with fields

class A
{
  public int somevalue;
  public string some         


        
相关标签:
7条回答
  • 2020-12-09 05:47

    There are many serializers:

    Part of .net framework

    • XmlSerializer (standardized format, slow and verbose)
    • BinarySerializer (proprietary format, medium speed, supports cyclic graphs, serializes fields instead of properties => annoying versioning)

    3rd party:

    • Json-Serializers (standardized format, text-based, shorter than xml)
    • ProtoBuf-Serializers (standardized format, binary, very fast)

    I'd probably use a ProtoBuf Serializer if the file may be binary, and a json serializer if it needs to be plain-text.

    0 讨论(0)
  • 2020-12-09 05:50

    Old topic, but I modified Tim Coker's answer above to utilize the using blocks to properly dispose of the stream objects and save only a single class instance at a time:

    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);
    }
    
    0 讨论(0)
  • 2020-12-09 06:02

    We can save and load objects from file in one of the following ways.

    BinarySerialization,XmlSerialization,JsonSerialization

    public enum Serialization
    {
        BinarySerialization = 1,
        XmlSerialization = 2,
        JsonSerialization = 3,
    }
    public static void SaveObjectToFile<T>(Serialization serialization, string filePath ,T objectToSave)
    {
        Directory.CreateDirectory(filePath.Substring(0, filePath.LastIndexOf('\\')));
         using (StreamWriter writer = new StreamWriter(filePath))
        {
            switch (serialization)
            {
                case Serialization.XmlSerialization: //Object type must have a parameterless constructor
                    XmlSerializer formatter = new XmlSerializer(typeof(T));
                    //Use the [XmlIgnore] attribute to exclude a public property or variable from being written to the file.(in XML Serialization only)
                    formatter.Serialize(writer, objectToSave);
                    break;
                case Serialization.JsonSerialization: //Object type must have a parameterless constructor
                    var contentsToWriteToFile = Newtonsoft.Json.JsonConvert.SerializeObject(objectToSave);
                    //[JsonIgnore] attribute to exclude a public property or variable from being written to the file.
                    writer.Write(contentsToWriteToFile);
                    break;
                case Serialization.BinarySerialization: 
                    var binaryFormatter = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
                    //decorate class (and all classes that it contains) with a [Serializable] attribute.Use the [NonSerialized] attribute to exclude a variable from being written to the file;
                    binaryFormatter.Serialize(writer.BaseStream, objectToSave);
                    break;
            }
        }
    }
    public static T LoadObjectToFile<T>(Serialization serialization, string filePath)
    {
        using (StreamReader reader = new StreamReader(filePath))
        {
            switch (serialization)
            {
                case Serialization.XmlSerialization:
                    XmlSerializer formatter = new XmlSerializer(typeof(T));
                    return (T)formatter.Deserialize(reader);
                case Serialization.JsonSerialization:
                    var fileContents = reader.ReadToEnd();
                    return Newtonsoft.Json.JsonConvert.DeserializeObject<T>(fileContents);
                case Serialization.BinarySerialization:
                    var binaryFormatter = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
                    return (T)binaryFormatter.Deserialize(reader.BaseStream);
                default:
                     throw new System.ArgumentOutOfRangeException("Serialization = "+Convert.ToString(serialization));
            }
        }
    }
    
    0 讨论(0)
  • 2020-12-09 06:03

    I just wrote a blog post on saving an object's data to Binary, XML, or Json; well writing an object or list of objects to a file that is. Here are the functions to do it in the various formats. See my blog post for more details.

    Binary

    /// <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

    Requires the System.Xml assembly to be included in your project.

    /// <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

    You must include a reference to Newtonsoft.Json assembly, which can be obtained from the 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();
        }
    }
    

    Example

    // 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");
    
    0 讨论(0)
  • 2020-12-09 06:07

    You can serialize your List<> using XML serializer or Binary Serializer and save the serialized list into a file.

    Later , you can read this file content and retrieve your original list.

    Make your type for which you are creating list [Serializable]

    0 讨论(0)
  • 2020-12-09 06:10

    I usually use the XML Serilizer, is fast, easy to implement and keep the objects in a hummand readable fashion, you can see a nice example.

    You can use a binary serialization if you want a more size effective obfustated solution. (for example if you want to transmit the serialization over a network.)

    EDIT: To get more control over the elements you serialize take a look of this example

    0 讨论(0)
提交回复
热议问题