StreamWriter перезаписывает предыдущие записи?

Привет, мне интересно, как я могу сохранить предыдущие записи с моей записью потока, если я использую приведенный ниже код, он отлично работает, когда создается запись студента, но когда я создаю вторую запись студента, предыдущая запись исчезла? Как я могу вести все записи?

    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()], так что я не уверен, что происходит?


person G Gr    schedule 28.04.2012    source источник


Ответы (3)


Используйте эту перегрузку конструктора StreamWriter для добавления новых данных вместо перезаписи.

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;
        }
    }
person Ňuf    schedule 28.04.2012
comment
Это не работает. Та же проблема, но вместо моего способа, которым вы не добавляете, также теряет формат xml в документе xml при втором запуске. - person G Gr; 29.04.2012
comment
WriteStudent выдает исключение: Type 'WcfServiceLibrary1.Student' in Assembly 'WcfServiceLibrary1, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' is not marked as serializable. - person G Gr; 29.04.2012
comment
@JungleBoogie: это означает, что вы должны украсить класс Student с помощью Serializable атрибут. - person Ňuf; 29.04.2012
comment
[Serializable()] public class Student если я попробую это сделать, я все равно получу ошибку? - person G Gr; 29.04.2012
comment
Я обновил свой вопрос, надеюсь, мы сможем закончить этот вопрос. - person G Gr; 29.04.2012
comment
@JungleBoogie: И ошибка точно такая же, включая WcfServiceLibrary1.Student? Если так, то у меня закончились идеи. Я протестировал его на своем компьютере, и он отлично работает. - person Ňuf; 29.04.2012
comment
Да, точно так же, интересно, может ли это быть мой хешированный пароль и поля соли? См. Мой обновленный вопрос. - person G Gr; 29.04.2012
comment
Я не использовал остальной код, потому что он не подходит для моей веб-службы, но он все равно должен работать? - person G Gr; 29.04.2012
comment
Даже если в вашем вопросе указан класс Student, как указано выше (включая пароль и соль), программа по-прежнему отлично работает на моем компьютере. Находится ли ваш класс Student в той же сборке, что и метод AddStudent? Если это не так, убедитесь, что вы ссылаетесь на актуальную версию сборки с классом Student (я много раз видел, что неправильно установленная ссылка на сборку в Visual Studio приводила к тому, что старая версия сборки перезаписывала текущую версию) - person Ňuf; 29.04.2012
comment
Нет, это в той же программе, правда не уверен, что происходит? - person G Gr; 29.04.2012
comment
Это может решить эту проблему. - person Ňuf; 29.04.2012
comment
Нуф, я заставил его работать, по какой-то причине мне пришлось поставить serilizable на каждый класс контракта данных (даже те, которые не использовались), не знаю, почему. У меня проблема, как мне прочитать файл .dat в сетке данных? - person G Gr; 29.04.2012

Вы открываете файл, отбрасываете существующее содержимое, сериализуете один объект student типа Student в XML, записываете XML в файл и закрываете его.

То, что вам нужно сделать, почти точно такое же, за исключением того, что вам нужно сериализовать список студентов, а не один. Для этого попробуйте сделать следующее:

s.Serialize(w, students);

вместо этого:

s.Serialize(w, student);

И не забудьте изменить typeof(Student) на тип того класса, который вы используете для ведения списка (это будет тип объекта students).

person Community    schedule 28.04.2012
comment
Привет, Влад, использующий студентов (как ни странно, так назван мой список ‹Student›, возвращает ошибку. Произошла ошибка при создании XML-документа ... да, спасибо Visual Studio, очень информативно! - person G Gr; 29.04.2012
comment
вы правы в том, что вы говорите, что я отбрасываю существующий контент, но я также хочу сериализовать одного студента, потому что это отдых wcf, и только один студент будет создан за раз, поэтому все, что я хочу сделать, это добавить следующий создана студенческая коллекция. - person G Gr; 29.04.2012
comment
@JungleBoogie: Тогда используйте ответ Нуфа :) Я имею в виду, правда, что еще ты можешь сделать? Разберите весь файл, добавьте учащегося в проанализированный список, затем снова сериализуйте его ... - person ; 29.04.2012

Это не сработает так, как вы ожидаете. StreamWriter не будет делать никаких волшебных действий, чтобы вставить вашу новую Student запись в корневой элемент. Вам нужно десериализовать список из файла, добавить новую запись и сериализовать ее обратно. В качестве альтернативы вы можете сохранить список учеников в памяти, добавить к нему новую запись и затем сериализовать весь набор.

Ни один из этих способов не является отличным способом хранения дополнительных обновлений. Вместо этого вам следует изучить возможность использования SQL Server (или экспресс-версии).

person Ilia G    schedule 29.04.2012