C# - 序列化/反序列化或保存/加载元组列表

标签 c# xml serialization tuples

我有一个列表,其中包含两个字符串和 25.000 个元素的元组

List<Tuple<string, string>> MyList

我尝试找到一种方法来保存此列表,然后加载它,因为每次从头开始构建MyList确实需要时间。我试过了

using System;
using System.IO;
using System.Text;
using System.Xml.Serialization;

namespace CopyFiles
{
/// <summary>
/// Serializer class.  Load and Save classes from/to XML files.
/// </summary>

public class XSerial
{
    /// <summary>
    /// Load a class from a serialized XML file.
    /// </summary>
    /// <param name="filename">full path or path relative to the XML file</param>
    /// <param name="t">type of the class that is being retrieved (Use typeof(ClassName))</param>
    /// <returns>A populated version of the class, or null on failure</returns>
    /// <exception cref="Exception">Can throw several exceptions for IO and serialization loading</exception>
    public static T Load<T>(string filename)
    {
        T ob = default(T);
        using (Stream s = File.Open(filename, FileMode.Open))
        {
            StreamReader sr = new StreamReader(s);
            ob = DeserializeObject<T>(sr.ReadToEnd());
            s.Close();
        }
        return ob;
    }

    /// <summary>
    /// Save an instance of a class to an XML file
    /// </summary>
    /// <param name="filename">Full or relative path to the file</param>
    /// <param name="cls">Class to serialize and save.</param>
    /// <param name="t">Type of the class (use: typeof(ClassName)</param>
    /// <returns>True on success, False on failure</returns>
    public static void Save<T>(string filename, T cls)
    {
        using (Stream s = File.Open(filename, FileMode.Create))
        {
            using (StreamWriter sw = new StreamWriter(s))
            {
                sw.Write(SerializeObject<T>(cls));
                sw.Close();
                s.Close();
                return;
            }
        }
    }


    /// <summary>
    /// Serialize the object into an XML format
    /// </summary>
    /// <typeparam name="T">Type of object to serialize</typeparam>
    /// <param name="pObject">the object to serialize</param>
    /// <returns>a string representing the XML version of the object</returns>
    public static String SerializeObject<T>(T pObject)
    {
        MemoryStream memoryStream = new MemoryStream();
        UTF8Encoding encoding = new UTF8Encoding();

        XmlSerializer xs = new XmlSerializer(typeof(T));
        System.Xml.XmlTextWriter xmlTextWriter = new System.Xml.XmlTextWriter(memoryStream, Encoding.UTF8);
        xs.Serialize(xmlTextWriter, (object)pObject);
        memoryStream = (MemoryStream)xmlTextWriter.BaseStream;
        return encoding.GetString(memoryStream.ToArray());
    }

    /// <summary>
    /// Deserialize the object back into the object from an XML string
    /// </summary>
    /// <typeparam name="T">Type of the object to restore</typeparam>
    /// <param name="pXmlizedString">The string that represents the object in XML</param>
    /// <returns>A new instance of the restored object</returns>
    public static T DeserializeObject<T>(String pXmlizedString)
    {
        UTF8Encoding encoding = new UTF8Encoding();
        XmlSerializer xs = new XmlSerializer(typeof(T));
        MemoryStream memoryStream = new MemoryStream(encoding.GetBytes(pXmlizedString));
        System.Xml.XmlTextWriter xmlTextWriter = new System.Xml.XmlTextWriter(memoryStream, Encoding.UTF8);
        return (T)xs.Deserialize(memoryStream);
    }
  }
}

它非常适合简单的列表<...>

class Program
{
    static void Main(string[] args)
    {
        List<string> MyList = null;
        try
        {
            MyList = XSerial.Load<List<string>>("MyList.xml");
        }
        catch (Exception e)
        {
            Console.WriteLine("Error: " + e.Message);
            // make sure the object won't cause errors.
            MyList = new List<string>();
        }

        Console.WriteLine("List Items:");
        foreach (string item in MyList)
        {
            Console.WriteLine("In list: " + item);
        }

        MyList.Add("Orange");
        MyList.Add("Blue");
        MyList.Add("Green");

        Console.WriteLine("Saving list...\n");
        try
        {
            XSerial.Save<List<string>>("MyList.xml", MyList);
        }
        catch (Exception e)
        {
            Console.WriteLine("Error Saving: " + e.Message);
            // nothing can be done about recovery.
        }

        Console.WriteLine("Press any key to continue...");
        Console.ReadKey();
    }
}

但不适用于带有元组的列表,因为 XmlSerializer 能够完成其工作需要默认构造函数。这是一个不带参数的构造函数。所有 Tuple<...> 类都有一个构造函数,并且该构造函数接受多个参数。

我的问题:上面的 XSerial 有没有办法完成元组列表的工作,或者我应该使用其他类似 http://msdn.microsoft.com/en-us/library/system.runtime.serialization.formatters.binary.binaryformatter.aspx 的东西? ?提前致谢。

最佳答案

我决定使用以下(二进制序列化)作为带有元组的案例列表

 List<Tuple<string, string>> MyList

我的代码

 List<Tuple<string, string>> MyList = new List<Tuple<string, string>>(); 

 if (File.Exists(@"filename.dat"))
        {
            //LOAD
            Console.WriteLine("Load filename.dat...");
            FileStream inStr = new FileStream(@"filename.dat", FileMode.Open);
            BinaryFormatter bf = new BinaryFormatter();
            MyList = bf.Deserialize(inStr) as List<Tuple<string, string>>;

        }
        else {
            //
            // Do here the list building/ Make the List<Tuple<string, string>> MyList
            //

            //SAVE
            FileStream stream = new FileStream(@"filename.dat", FileMode.Create);
            BinaryFormatter formatter = new BinaryFormatter();
            formatter.Serialize(stream, MyList);
            stream.Close();            
        }

就我而言,在我的笔记本电脑中,列表构建大约需要 6 分钟(约 33.000 个元组元素),并且从我拥有“filename.dat”时起,只需 1 秒即可加载它,以便在我的程序中进一步使用。

关于C# - 序列化/反序列化或保存/加载元组列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20823698/

相关文章:

javascript - 如何使用 postMessage 作为序列化程序来隔离消息?

c# - 将 JSON 数组序列化为类的实例

C# SQL 查询滞后

c# - 无法更新 EntitySet - 因为它有一个 DefiningQuery 并且不存在 <UpdateFunction> 元素

c# - Linq FirstOrDefault 每次迭代都会评估谓词?

java - Grails 无法接收序列化数据

c# - 如何读取 XML 以创建 resx 文件

Android 无法取消选择 TextView

java - 如何包装 jackson 序列化异常

c# - Linq to Xml 选择元素