101 votes

Comment sauvegarder/restaurer un objet sérialisable vers/depuis un fichier ?

J'ai une liste d'objets et je dois l'enregistrer quelque part dans mon ordinateur. J'ai lu quelques forums et je sais que l'objet doit être Serializable . Mais ce serait bien si je pouvais avoir un exemple. Par exemple, si j'ai ce qui suit :

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

SomeClass object1 = new SomeClass { someProperty = "someString" };

Mais comment puis-je stocker object1 quelque part dans mon ordinateur et de le récupérer plus tard ?

3 votes

Voici un tutoriel qui montre comment sérialiser vers un fichier switchonthecode.com/tutoriel/

171voto

deadlydog Points 1840

Je viens d'écrire un article de blog sur l'enregistrement des données d'un objet au format Binary, XML ou Json . Vous avez raison de dire que vous devez décorer vos classes avec l'attribut [Serializable], mais seulement si vous utilisez la sérialisation binaire. Vous pouvez préférer utiliser la sérialisation XML ou Json. Voici les fonctions pour le faire dans les différents formats. Voir mon article de blog pour plus de détails.

Binaire

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

Nécessite l'inclusion de l'assembly System.Xml dans votre projet.

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

Vous devez inclure une référence à l'assemblage Newtonsoft.Json, qui peut être obtenu à partir du fichier Paquet 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();
    }
}

Exemple

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

150voto

Alex Mendez Points 2288

Vous pouvez utiliser les éléments suivants :

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

1 votes

C'est bien ! Bien que string attributeXml = string.Empty; en DeSerializeObject n'est jamais utilisé ;)

3 votes

Il n'est pas nécessaire d'appeler la méthode close sur un lecteur dans votre bloc d'utilisation. Dispose() est implicite et aura lieu même si une exception est levée dans le bloc avant la méthode explicite Close(). Bloc de code très utile.

2 votes

Comment sauvegarder une liste d'objets à l'aide de cette fonction Je l'ai utilisée mais elle ne sauvegarde que le dernier objet de ma liste.

30voto

AllenG Points 6242

Vous devrez sérialiser vers quelque chose : c'est-à-dire choisir binaire, ou xml (pour les sérialiseurs par défaut) ou écrire un code de sérialisation personnalisé pour sérialiser vers une autre forme de texte.

Une fois que vous avez choisi cela, votre sérialisation appellera (normalement) un flux qui écrit dans une sorte de fichier.

Ainsi, avec votre code, si j'utilisais la sérialisation 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);
}

Ensuite, il faut désérialiser :

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

    var myObject = _xSer.Deserialize(fs);
}

NOTE : Ce code n'a pas été compilé, et encore moins exécuté - il peut y avoir des erreurs. De plus, il suppose une sérialisation/désérialisation complètement prête à l'emploi. Si vous avez besoin d'un comportement personnalisé, vous devrez faire du travail supplémentaire.

12voto

Emdadul Sawon Points 2362

1. Restaurer un objet à partir d'un fichier

De Ici vous pouvez désérialiser un objet à partir d'un fichier de deux manières.

Solution-1 : Lire le fichier dans une chaîne de caractères et désérialiser JSON dans un type.

string json = File.ReadAllText(@"c:\myObj.json");
MyObject myObj = JsonConvert.DeserializeObject<MyObject>(json);

Solution-2 : Désérialiser JSON directement à partir d'un fichier

using (StreamReader file = File.OpenText(@"c:\myObj.json"))
{
    JsonSerializer serializer = new JsonSerializer();
    MyObject myObj2 = (MyObject)serializer.Deserialize(file, typeof(MyObject));
}

2. Enregistrer l'objet dans le fichier

de aquí vous pouvez sérialiser un objet dans un fichier de deux manières.

Solution-1 : Sérialiser JSON en une chaîne de caractères, puis écrire la chaîne dans un fichier

string json = JsonConvert.SerializeObject(myObj);
File.WriteAllText(@"c:\myObj.json", json);

Solution-2 : Sérialiser JSON directement dans un fichier

using (StreamWriter file = File.CreateText(@"c:\myObj.json"))
{
    JsonSerializer serializer = new JsonSerializer();
    serializer.Serialize(file, myObj);
}

3. Extra

Vous pouvez télécharger Newtonsoft.Json à partir de NuGet en suivant la commande suivante

Install-Package Newtonsoft.Json

2voto

ozanmut Points 454

Vous pouvez utiliser JsonConvert de la bibliothèque Newtonsoft. Pour sérialiser un objet et l'écrire dans un fichier au format json :

File.WriteAllText(filePath, JsonConvert.SerializeObject(obj));

Et de le désérialiser en objet :

var obj = JsonConvert.DeserializeObject<ObjType>(File.ReadAllText(filePath));

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X