Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > .NET Frameworks (точка нет фреймворки) > Общие вопросы .NET
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 13.03.2010, 02:52   #1
Casper-SC
Форумчанин
 
Регистрация: 04.07.2007
Сообщений: 549
По умолчанию Сохранить массив классов в файл

Здравствуйте! Появился такой вопрос: Как сохранить массив классов в файл? Вот есть у меня класс, в нём много полей и методов. На форме есть кнопка "Новый", нажимаю на неё и появляется форма в ней я всё настраиваю как мне надо и жму "ОК", создаётся экземпляр моего класса с настройками и в ListView добавляется строка ListViewItem (режим - View == Details) и к свойству Tag привязывается тот экземпляр класса.
Код:
...
this.listViewAlarm.Items[i].Tag = MyClass;
...
В этом классе все настройки хранятся в его полях, вот мне и нужно как то сохранить всё это в файл, а потом прочитать из него если надо. Как это сделать? Я в курсе про System.IO и про всякие FileStream, MemoryStream, но я что-то не понимаю как сохранять экземпляр класса или хотя бы какую либо структуру. Даже книжку по этой теме щас читаю, а там примеры вообще не в ту степь, там текст сохраняют и т.д.
Casper-SC вне форума Ответить с цитированием
Старый 13.03.2010, 02:56   #2
TaTT DoGG
Форумчанин
 
Аватар для TaTT DoGG
 
Регистрация: 25.04.2008
Сообщений: 476
По умолчанию

сериализация

using System.Xml.Serialization;

Код:
try
{
   //Сериализуем полученное
   XmlWriter writer = new XmlTextWriter("c:\\serializeExample.xml", System.Text.Encoding.UTF8);
   XmlSerializer serializer = new XmlSerializer(typeof(class_name)); //class_name - имя класса
   serializer.Serialize(writer, sd); //sd - переменная класса
   writer.Close();
   MessageBox.Show("Объект успешно сериализован в файл c:\\serializeExample.xml", "Операция выполнена",
      MessageBoxButtons.OK, MessageBoxIcon.Information);
}
   catch (Exception exc)
{
   MessageBox.Show(exc.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
}

десериализация:
Код:
try
{
   //Попробуем десериализовать файл serializeExample.xml в корне диска C
   XmlReader reader = new XmlTextReader("c:\\serializeExample.xml");
   XmlSerializer serializer = new XmlSerializer(typeof(class_name)); //class_name - имя класса
   SerializableData sd = (class_name)serializer.Deserialize(reader); //sd - переменная класса
   reader.Close();
   MessageBox.Show("Объект успешно десериализован из файла c:\\serializeExample.xml", "Операция выполнена",
      MessageBoxButtons.OK, MessageBoxIcon.Information);
}
catch (Exception exc)
{
   MessageBox.Show(exc.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
под массивом класса имеется ввиду List<>?
Life if about choices
Make the right choice

Последний раз редактировалось TaTT DoGG; 13.03.2010 в 03:04.
TaTT DoGG вне форума Ответить с цитированием
Старый 13.03.2010, 03:05   #3
Casper-SC
Форумчанин
 
Регистрация: 04.07.2007
Сообщений: 549
По умолчанию

Цитата:
под массивом класса имеется ввиду <List>?
Я пока даже и не знаю, по идее не обязательно же <List> использовать, если всё загружается в ListView, ну привязывается к Tag. Позже попробую сохранить этим способом.

Делаю так:

Код:
           try
            {
                //Сериализуем полученное
                XmlWriter writer = new XmlTextWriter("c:\\serializeExample.xml", System.Text.Encoding.UTF8);
                XmlSerializer serializer = new XmlSerializer(typeof(MyClass)); //class_name - имя класса
                for (int i = 0; i < listViewMyClass.Items.Count; i++)
                {
                    serializer.Serialize(writer, (MyClass)listViewMyClass.Items[i].Tag); //sd - переменная класса
                }
                writer.Close();
                MessageBox.Show("Объект успешно сериализован в файл c:\\serializeExample.xml", "Операция выполнена",
                   MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
            catch (Exception exc)
            {
                MessageBox.Show(exc.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }
появляется такая ошибка:

Возникла ошибка при отражении типа "WindowsFormsApplication1.MyCla ss".

Последний раз редактировалось Stilet; 15.03.2010 в 12:16.
Casper-SC вне форума Ответить с цитированием
Старый 13.03.2010, 03:21   #4
TaTT DoGG
Форумчанин
 
Аватар для TaTT DoGG
 
Регистрация: 25.04.2008
Сообщений: 476
По умолчанию

это я выложил сохранение обычного класса (не массив)
вот только что набросал сохранение и считывание листа классов:

сам класс
Код:
public class MyClass
    {
        private string _StringElement;
        private int _VersionNum;

        public int VersionNum
        {
            get { return _VersionNum; }
            set { _VersionNum = value; }
        }

        public string StringElement
        {
            get { return _StringElement; }
            set { _StringElement = value; }
        }

        //Открытый конструктор без параметров является необходимым для сериализации
        public MyClass()
        { }

        public MyClass(string a, int b)
        {
            this._VersionNum = b;
            this._StringElement = a;        
        }
    }
заполнение листа
Код:
List<MyClass> sd = new List<MyClass>();
            sd.Add(new MyClass("1",1));
            sd.Add(new MyClass("2", 2));
            sd.Add(new MyClass("3", 3));
сериализация листа классов:
Код:
                XmlWriter writer = new XmlTextWriter("c:\\serializeExample.xml", System.Text.Encoding.UTF8);
                XmlSerializer serializer = new XmlSerializer(typeof(List<MyClass>));
                serializer.Serialize(writer, sd);
                writer.Close();
десериализция листа классов:
Код:
    XmlReader reader = new XmlTextReader("c:\\serializeExample.xml");
                XmlSerializer serializer = new XmlSerializer(typeof(List<MyClass>));
                List<MyClass> sd = (List<MyClass>)serializer.Deserialize(reader);
                reader.Close();
                Console.WriteLine(sd[1].StringElement);
                Console.ReadKey();
десериализировал, считал список в listview и работай дальше.
для сохранения, заполнил лист классов из listview и сериализировал его
я бы сделал именно так
Life if about choices
Make the right choice
TaTT DoGG вне форума Ответить с цитированием
Старый 13.03.2010, 03:25   #5
TaTT DoGG
Форумчанин
 
Аватар для TaTT DoGG
 
Регистрация: 25.04.2008
Сообщений: 476
По умолчанию

Цитата:
Сообщение от Casper-SC Посмотреть сообщение
Делаю так:

Код:
           try
            {
                //Сериализуем полученное
                XmlWriter writer = new XmlTextWriter("c:\\serializeExample.xml", System.Text.Encoding.UTF8);
                XmlSerializer serializer = new XmlSerializer(typeof(MyClass)); //class_name - имя класса
                for (int i = 0; i < listViewMyClass.Items.Count; i++)
                {
                    serializer.Serialize(writer, (MyClass)listViewMyClass.Items[i].Tag); //sd - переменная класса
                }
                writer.Close();
                MessageBox.Show("Объект успешно сериализован в файл c:\\serializeExample.xml", "Операция выполнена",
                   MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
            catch (Exception exc)
            {
                MessageBox.Show(exc.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }
появляется такая ошибка:

Возникла ошибка при отражении типа "WindowsFormsApplication1.MyCla ss".
serializer.Serialize(writer,MyClass ) сразу сериализирует весь класс MyClass
а ты это делаешь в цикле много раз

принцип работы:
запуск программы -> десериализация в класс -> заполнение listview из класса -> работа с listview -> при выходе ( заполнеие класса из listview -> сериализация класса)

вот написал быстренько проект как тебе нужно работать. если есть вопросы спрашивай
Вложения
Тип файла: rar Сериализация массива классов.rar (36.7 Кб, 17 просмотров)
Life if about choices
Make the right choice

Последний раз редактировалось Stilet; 15.03.2010 в 12:21.
TaTT DoGG вне форума Ответить с цитированием
Старый 13.03.2010, 03:52   #6
m0nax
Форумчанин
 
Аватар для m0nax
 
Регистрация: 25.09.2009
Сообщений: 525
По умолчанию

дался всем этот ХМЛ, кроме него есть еще BinaryFormatter, проще и быстрей все делается
Код:
		
		BinaryFormatter formatter = new BinaryFormatter();
				using (Stream stream = File.Create("123.bin"))
				{
					formatter.Serialize(stream, Массив_объектов_класса);
					stream.Close();
				}
обратно так же как с хмл, массив = десериализация()
m0nax вне форума Ответить с цитированием
Старый 13.03.2010, 03:55   #7
TaTT DoGG
Форумчанин
 
Аватар для TaTT DoGG
 
Регистрация: 25.04.2008
Сообщений: 476
По умолчанию

тот же xml только вид сбоку )

Код:
		
BinaryFormatter formatter = new BinaryFormatter(); //= XmlSerializer serializer = new XmlSerializer(typeof(List<MyClass>));
Stream stream = File.Create("123.bin"); //= XmlWriter writer = new XmlTextWriter("c:\\serializeExample.xml", System.Text.Encoding.UTF8);
formatter.Serialize(stream, Массив_объектов_класса); //= serializer.Serialize(writer, sd);
stream.Close(); //= writer.Close();
Life if about choices
Make the right choice

Последний раз редактировалось TaTT DoGG; 13.03.2010 в 03:58.
TaTT DoGG вне форума Ответить с цитированием
Старый 13.03.2010, 11:57   #8
Casper-SC
Форумчанин
 
Регистрация: 04.07.2007
Сообщений: 549
По умолчанию

Цитата:
Код:
        //Открытый конструктор без параметров является необходимым для сериализации
        public MyClass()
        { }
А если у меня есть уже такой конструктор, только он не пустой, а присваивает полям класса начальные значения, он подходит? Просто я делаю так:
Код:
            List<MyClass> list = new List<MyClass>();
            for (int i = 0; i < this.listViewMyClass.Items.Count; i++)
            {
                list.Add((MyClass)this.listViewMyClass.Items[i].Tag);
            }
            XmlWriter xmlWriter = new XmlTextWriter("E:\\serializedClasses.xml", System.Text.Encoding.UTF8);
            XmlSerializer serializer = new XmlSerializer(typeof(List<MyClass>));
            serializer.Serialize(xmlWriter, list);
            xmlWriter.Close();
И у меня на строчке:
Код:
 XmlSerializer serializer = new XmlSerializer(typeof(List<MyClass>));
Вылетает такая ошибка:
Цитата:
Возникла ошибка при отражении типа "System.Collections.Generic.Lis t`1[WindowsFormsApplication1.MyClass]".
Ума не приложу почему такая проблема?
В классе используются в качестве полей перечисления (enum) объявленные вне класса. Может это причина? Просто я не понимаю вообще из-за чего это может быть и что конкретно не может сделать компилятор.

Последний раз редактировалось Casper-SC; 13.03.2010 в 13:49.
Casper-SC вне форума Ответить с цитированием
Старый 13.03.2010, 14:00   #9
TaTT DoGG
Форумчанин
 
Аватар для TaTT DoGG
 
Регистрация: 25.04.2008
Сообщений: 476
По умолчанию

в классе может быть сколько угодно конструкторов. для сериализации обязательно должен быть 1 пустой

Код:
list.Add((MyClass)this.listViewMyClass.Items[i].Tag);
это что?
нужно так:
Код:
list.Add(new MyClass(тут переменные для твоего конструктора));
в list.Add() создается ещё один экземпляр класса
Life if about choices
Make the right choice

Последний раз редактировалось TaTT DoGG; 13.03.2010 в 14:05.
TaTT DoGG вне форума Ответить с цитированием
Старый 13.03.2010, 15:16   #10
Casper-SC
Форумчанин
 
Регистрация: 04.07.2007
Сообщений: 549
По умолчанию

Зачем мне переменные для моего конструктора? Это я буду создавать новый класс, но зачем, если уже есть настроенный, видимо мы друг друга не понимаем и говорим немного о разных вещах. Если мне создать пустой конструктор, то придётся много менять в коде программы, так как у меня уже есть конструктор без параметров, но он не пустой. Я попробовал в конструкторе закоментировать всё кроме самого конструктора, всё равно та же ошибка.

Код:
list.Add((MyClass)this.listViewMyClass.Items[i].Tag);
Это настроенный и привязанный к элементу списка класс, то есть в списке например 10 элементов, то и 10 экземпляров класса привязано к ListView, а точнее к его свойству Tag. Кстати при отладке проверял, в лист добавляется привязанный к свойству Tag MyClass, элемента списка ListViewItem. Кстати в моём классе в полях не только перемнные, но и перечисления объявленные вне класса, один List<WayForFileRun>, WayForFileRun - структура это.
Casper-SC вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
создать двумерный массив, заполнить случайными числами, сохранить в файл buba Паскаль, Turbo Pascal, PascalABC.NET 7 17.03.2015 20:08
Передать массив базового абстрактного класса функциям производных классов mishutka999 Общие вопросы C/C++ 2 01.12.2009 14:08
запись классов в бинарный файл Feannewedd Общие вопросы C/C++ 6 29.06.2009 10:11
Массив классов nns2009 Общие вопросы C/C++ 15 03.02.2009 00:47