将类反序列化为文件并返回列表

Posted

技术标签:

【中文标题】将类反序列化为文件并返回列表【英文标题】:Deserializing a class into a file and back into a list 【发布时间】:2022-01-02 01:23:36 【问题描述】:

我正在尝试将 csv 文件反序列化为列表。 如果有更好的方法将我的班级数据发送到文件中,然后将其重新组合到列表中,请告诉我。

班级:

[Serializable]
public class Student

    int studentID;
    string studentName;
    string studentAge;

名单:

List<Student> students = new List<Student>();
students.studentID = txt_sID.Text;
students.studentName = txt_sName.Text;
students.studentAge = txt_sAge.Text;

序列化器:

XmlSerializer SerializerObj = new XmlSerializer(typeof(Student));
TextWriter WriteFileStream = new StreamWriter(@"students.csv", true);
SerializerObj.Serialize(WriteFileStream, students);
WriteFileStream.Close();

反序列化器:

XmlSerializer serializer = new XmlSerializer(typeof(Student));
using (Stream reader = new FileStream(@"students.csv", FileMode.Open))

    Student students2 = (Student)serializer.Deserialize(reader);
    students.Add(students2);

错误:

XmlException: Unexpected XML declaration. The XML declaration must be the first node in the document, and no whitespace characters are allowed to appear before it.

CSV 文件内容:

<?xml version="1.0" encoding="utf-8"?>
<Student xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <studentID>1</studentID>
  <studentName>Jonathan Joestar</studentName>
  <studentAge>21</studentAge>
</Student><?xml version="1.0" encoding="utf-8"?>

我尝试过的:

使用 XmlWriter.Create 作为序列化程序来摆脱 Xml 标记。 csv 文件必须接受多个条目并放回列表中,而 XmlWriter.Create 一次只能处理一个条目 (?)。

诚挚的问候并感谢您的宝贵时间。

【问题讨论】:

为什么要混淆 CSV 和 XML?这些是完全不同的数据序列化方式。 Xml 是更通用,但也更冗长的方式。 老实说,我不知道。我正在尝试学习将数据放入列表并返回,这是向我建议的 作为 XML,您的文档格式不正确。它最后有一个额外的 XML 声明 &lt;?xml version="1.0" encoding="utf-8"?&gt;,不应该在那里。应该只有一个 XML 声明,并且应该出现在文档的开头。因此错误 XmlException: Unexpected XML declaration. 正确地解释了您的文档的问题。您也可以将您的 XML 上传到 xmlvalidation.com 以确认这是问题所在。要解决此问题,您应该修复生成格式错误的 XML 的代码。 最后你得到了&lt;?xml version="1.0" encoding="utf-8"?&gt;,因为你正在使用附加文件的new StreamWriter(String, true)构造函数打开。 【参考方案1】:

我建议忽略 CSV 而专注于 XML。 CSV 文件本质上代表一个表,这不能代表任意对象层次结构。所以在这方面xml更加灵活。

要序列化对象列表,您应该在序列化时指定列表类型。 IE。 List&lt;Student&gt;Student[]。完整示例:

        [Serializable]
        public class Student
        
            public int Id;
            public string Name;
            public float Age;

            public Student()  
            public Student(int id, string name, float age)
            
                Id = id;
                Name = name;
                Age = age;
            
        

        public void SerializeDeserialize()
        
            var xmlSerializer = new XmlSerializer(typeof(Student[]));
            var ms = new MemoryStream();
            var students = new Student[]
            
                new Student(1, "Bob", 42),
                new Student(2, "Alice", 22.4f)
            ;
            xmlSerializer.Serialize(ms, students);
            ms.Position = 0; // Reset stream to allow it to be deserialized
            var deserialized = (Student[])xmlSerializer.Deserialize(ms);
        

将内存流替换为要保存到文件的文件流。

请注意,虽然 xml 非常好,但大多数行业正在转向 json。据我所知,json 并没有任何真正的技术优势,所以它更多的是一个不那么冗长和拥有更好的序列化库的问题。

【讨论】:

以上是关于将类反序列化为文件并返回列表的主要内容,如果未能解决你的问题,请参考以下文章

Boost 将派生类反序列化为基类指针

将类序列化为 .json 文件

Jackson - 使用泛型类反序列化

序列化 numpy 数组列表并读回/反序列化为 Javascript

使用 datagridview 将列表序列化为现有的 .Json 文件

C#中通过XmlSerializer类反序列化多个同名XML元素