【问题标题】:StreamWriter overwriting previous records?StreamWriter 覆盖以前的记录?
【发布时间】:2012-04-28 23:22:28
【问题描述】:

您好我想知道如何使用我的流编写器保留以前的记录,如果我使用下面的代码,它在创建学生记录时可以正常工作,但是当我创建第二个学生记录时,以前的记录消失了?如何保留所有记录?

    public void AddStudent(Student student)
    {
        students.Add(student);
        XmlSerializer s = new XmlSerializer(typeof(Student));
        TextWriter w = new StreamWriter("c:\\list.xml");
        s.Serialize(w, student);
        w.Close();
    }

编辑更新:

从下面的部分答案中,我不断收到此错误Type WcfServiceLibrary1.Student' in Assembly 'WcfServiceLibrary1, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null is not marked as serializable

我已经用[Serializable()] 装饰了学生班,所以我不确定发生了什么?

【问题讨论】:

    标签: c# linq collections xml-serialization streamwriter


    【解决方案1】:

    使用 StreamWriter 构造函数的this 重载来追加新数据而不是覆盖。

    TextWriter w = new StreamWriter("c:\\list.xml", true);
    


    更新: 我明白了,它仅适用于 BinaryFormatter 而不适用于 XmlSerializer,因为第二次写入会使 XML 无效。除非出于某种原因需要 XML 格式,否则使用二进制格式会更容易。这应该有效:

       static void WriteStudent(Student S)
        {
            BinaryFormatter f = new BinaryFormatter();
            using (Stream w = new FileStream("c:\\list.dat", FileMode.Append))
            {
                f.Serialize(w, S);
            }
        }
    
        static List<Student> ReadStudents()
        {
            BinaryFormatter f = new BinaryFormatter();
    
            using (Stream w = new FileStream("c:\\list.dat", FileMode.Open))
            {
                List<Student> students = new List<Student>();
                while (w.Position < w.Length)
                {
                    students.Add((Student)f.Deserialize(w));
                }
                return students;
            }
        }
    

    【讨论】:

    • 这不起作用。同样的问题,但不是我的方式,您在第二次运行时不附加的方式也会丢失 xml 文档中的 xml 格式。
    • WriteStudent 抛出异常:Type 'WcfServiceLibrary1.Student' in Assembly 'WcfServiceLibrary1, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' is not marked as serializable.
    • @JungleBoogie:这意味着你必须用Serializable 属性装饰Student类。
    • [Serializable()] public class Student 如果我尝试这个我仍然得到错误?
    • 我已经更新了我的问题,希望我们可以完成这个问题。
    【解决方案2】:

    您正在做的是打开一个文件,丢弃现有内容,将Student 类型的单个student 对象序列化为 XML,将 XML 写入文件并关闭它。

    您要做的几乎完全相同,只是您必须序列化学生列表而不是单个学生。为此,请尝试这样做:

    s.Serialize(w, students);
    

    而不是这个:

    s.Serialize(w, student);
    

    别忘了将typeof(Student) 更改为您用来维护列表的任何类的typeof(这将是students 对象的类型)。

    【讨论】:

    • 嗨,弗拉德正在使用学生(有趣的是,我的列表 被命名为返回错误。生成 XML 文档时出错......是的,非常感谢 Visual Studio 提供的信息!跨度>
    • 你说的没错,我正在丢弃现有的内容,但我也想序列化一个学生,因为这是一个 wcf 休息,一次只会创建一个学生,所以所有我想做的是“追加”下一个创建的学生集合。
    • @JungleBoogie:然后使用 Nuf 的回答 :) 我的意思是,真的,你还能做什么?解析整个文件,将一个学生添加到解析列表中,然后再次序列化它......
    【解决方案3】:

    它不会按您期望的方式工作。 StreamWriter 不会在根元素内插入新的 Student 记录。您需要从文件中反序列化列表,添加新条目并将其序列化回来。或者,您可以将学生列表保存在内存中,向其中添加新记录,然后对整个集合进行序列化。

    这些都不是存储增量更新的特别好方法。您应该考虑改用 SQL Server(或 express)。

    【讨论】:

      猜你喜欢
      • 2018-03-28
      • 1970-01-01
      • 1970-01-01
      • 2010-10-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-11-08
      相关资源
      最近更新 更多