
- •Лабораторная работа №3. Ввод, вывод и сериализация объектов
- •1. Цель работы
- •2. Сведения из теории
- •2.1. Пространство имен System.Io
- •2.2. Классы потоков
- •2.3. Текстовые файлы
- •2.4. Двоичные файлы
- •2.5. Сериализация объектов
- •3. Пример выполнения работы
- •3.1. Визуальное проектирование диалогового окна
- •3.2. Проектирование программного кода
- •4. Задание для самостоятельной работы
Лабораторная работа №3. Ввод, вывод и сериализация объектов
1. Цель работы
Изучить пространства имен и классы библиотеки .NET Framework, используемые для ввода-вывода данных. Познакомиться с понятием и методами сериализации и десериализации объектов.
2. Сведения из теории
2.1. Пространство имен System.Io
Пространство имен System.IO содержит в себе большой набор типов, которые предназначены для выполнения операций с файлами и другими операциями ввода/вывода. Большинство классов System.IO предназначено для работы с каталогами и файлами на диске. Однако есть и такие типы, которые позволяют работать с буферами в оперативной памяти или с областями оперативной памяти напрямую. Наиболее важные неабстрактные классы System.IO представлены в таблице:
Класс |
Описание |
BinaryReader BinaryWriter |
Позволяют сохранять и извлекать информацию типов данных-примитивов (целочисленных, логических, строковых и т.п.) как двоичные значения |
BufferedStream |
Обеспечивает временное хранилище для потока байтов (например, для последующего переноса в постоянное хранилище) |
Directory DirectoryInfo File FileInfo |
Используются для работы со свойствами указанного каталога или физического файла, а также для создания новых файлов и расширения существующей структуры каталогов. Возможности классов File и Directory реализованы главным образом в виде статических методов. Классы DirectoryInfo и FileInfo работают через обычные объекты данных классов |
FileStream |
Обеспечивает произвольный доступ к файлу, представляемому как поток байтов |
MemoryStream |
Также обеспечивает произвольный доступ к потоку байтов, но уже не в виде физического файла, а в оперативной памяти |
StreamWriter StreamReader |
Используются для считывания из файла или записи в файл текстовой информации. Произвольный доступ к файлам при помощи этого класса не поддерживается |
StringWriter StringReader |
Эти классы также предназначены для работы с текстовой информацией, однако они применяются для работы с буфером в оперативной памяти, а не с файлом на диске |
Помимо обычных классов, представленных в таблице, в System.IO предусмотрено также большое количество перечислений и абстрактных классов. Абстрактные классы (Stream, TextReader, TextWriter и т.п.) определяют общие полиморфические интерфейсы для производных классов. Некоторые из этих абстрактных и производных классов далее рассмотрены более подробно.
2.2. Классы потоков
Центральную часть потоковой C#-системы занимает абстрактный класс System.IO.Stream. Класс Stream представляет байтовый поток и является базовым для всех остальных потоковых классов. Все классы, производные от Stream, предназначены для работы с блоками двоичных данных (для текстовых данных есть свои классы).
Иерархия классов, производных от System.IO.Stream, представлена на рисунке 4.1.
Рис. 4.1. Классы, производные от Stream
В классе Stream определен набор стандартных потоковых операций. Наиболее применяемые методы, определенные в классе Stream, перечислены в таблице:
Метод |
Описание |
void Close() |
Закрывает поток |
void Flush() |
Записывает содержимое потока в физическое устройство |
int ReadByte() |
Считывает один байт из текущего потока. При обнаружении конца файла возвращает -1 |
int Read(byte[] buf, int offset, int numBytes) |
Считывает numBytes байт в массив buf, начиная с элемента buf[offset], возвращает количество успешно прочитанных байт |
long Seek(long offset, SeekOrigin origin) |
Устанавливает текущую позицию потока равной смещению offset от заданного начала отсчета origin |
void WriteByte(byte b) |
Записывает один байт в выходной поток |
void Write(byte[] buf, int offset, int numBytes) |
Записывает диапазон размером numBytes байт из массива buf, начиная с элемента buf[offset] |
В общем случае при возникновении ошибки ввода-вывода приведенные методы генерируют исключение типа IOException. При попытке выполнить некорректную операцию, например, записать данные в поток, предназначенный только для чтения, генерируется исключение типа NotSupportedException.
В классе Stream определены методы, которые считывают и записывают данные. Однако не все потоки поддерживают все эти операции, поскольку возможен вариант, когда поток открывается только для чтения или только для записи. Кроме того, не все потоки поддерживают функцию установки в заданную позицию с помощью метода Seek(). Чтобы определить возможности потока, следует использовать соответствующие свойства класса Stream. Свойства приведены в следующей таблице:
Свойство |
Описание |
bool CanRead |
Свойство только для чтения. Равно true, если из потока можно считывать данные |
bool CanSeek |
Свойство только для чтения. Равно true, если поток поддерживает функцию установки в заданную позицию |
bool CanWrite |
Свойство только для чтения. Равно true, если в поток можно записывать данные |
long Length |
Свойство только для чтения. Содержит длину потока |
long Position |
Свойство для чтения и для записи. Представляет текущую позицию потока |
Чтобы создать байтовый поток, связанный с файлом, нужно создать объект класса FileStream. В этом классе определено несколько конструкторов. Чаще всего из них используется следующий:
FileStream(string filename, FileMode mode)
Этот конструктор открывает файл для доступа с разрешением чтения и записи. Здесь элемент filename означает имя файла, который необходимо открыть, причем оно может включать полный путь к файлу. Элемент mode означает режим открытия файла и может принимать одно из значений, определенных перечислением FileMode:
Значение |
Описание |
FileMode.Append |
Добавляет выходные данные в конец файла |
FileMode.Create |
Создает новый выходной файл. Существующий файл с таким же именем будет удален |
FileMode.CreateNew |
Создает новый выходной файл. Файл с таким же именем не должен существовать |
FileMode.Open |
Открывает существующий файл |
FileMode.OpenOrCreate |
Открывает файл, если он существует. В противном случае создает новый |
FileMode.Truncate |
Открывает существует файл, но усекает его длину до нуля |
Если попытка открыть файл оказалась неуспешной, генерируется исключение. Если файл невозможно открыть по причине его отсутствия, генерируется исключение FileNotFoundException. Если файл невозможно открыть из-за ошибки ввода/вывода, генерируется исключение типа IOException. Возможны также исключения следующих типов: ArgumentNullException (если имя файла представляет собой null-значение), ArgumentException (если некорректен параметр mode), SecurityException (если пользователь не обладает правами доступа) и DirectoryNotFoundException (если некорректно задан каталог).
Если необходимо ограничить доступ только чтением или только записью, нужно использовать следующий конструктор:
FileStream(string filename, FileMode mode, FileAccess how)
Значение, передаваемое с помощью параметра how, определяет способ доступ к файлу. Этот параметр может принимать одно из значений, определенных перечислением FileAccess: FileAccess.Read, FileAccess.Write, FileAccess.ReadWrite.