Министерство образования Республики Беларусь БЕЛОРУССКО-РОССИЙСКИЙ УНИВЕРСИТЕТ КАФЕДРА ПОИТ
Курс
"Основы алгоритмизации и программирования"
Методические указания
по лабораторной работе №16
Файлы
г. Могилев 2014
1 Цель работы
Целью лабораторной работы является:
Изучение принципов работы с файлами;
Изучение классов связанных с файловыми операциями.
2 Ход работы
2.1 Получение индивидуального задания
Вначале следует получить индивидуальное задание у преподавателя, проводящего лабораторную работу. Варианты заданий приводятся в разделе 5.
2.2 Оформление отчета
Отчет оформляется индивидуально каждым студентом. Отчет должен содержать задание, алгоритм и листинг программы.
3 Содержание отчета
Отчет по лабораторной работе выполняется на листах формата А4. В состав отчета входят:
титульный лист;
цель работы;
текст индивидуального задания;
выполнение индивидуального задания.
4 Краткие теоретические сведения
4.1 Создание потоков, связанных с файлами
Если вам нужно создать входной или выходной поток, связанный с локальным файлом, содержащим двоичные данные, следует воспользоваться классами BinaryWriterиBinaryReaderиз библиотекиMicrosoft.NETFramework. Что же касается чтения из файла или записи в файл текстовых данных, то для решения этой задачи обычно используются классыStreamReaderиStreamWriter.
В любом случае, перед тем как читать данные из файла или записывать их в файл, необходимо выполнить операцию открытия потока, связанного с файлом. Когда работа с файлом окончена, соответствующий поток необходимозакрыть явным образом.
Открытие потока FileStream
Для работы с двоичными файлами ваша программа должна вначале создать поток класса FileStream, воспользовавшись соответствующим конструктором, например:
FileStream fs = new FileStream("mayfile.dat", FileMode.CreateNew);
В качестве первого параметра конструктору необходимо передать полный путь к файлу или имя файла, а в качестве второго — режим открытия потока (табл. 4.1).
Таблица 4.1 - Режимы открытия файла FileMode
Режим |
Описание | |
Append |
Если файл существует, он открывается. Текущая позиция устанавливается на конец файла. Если указанного файла нет, то он создается. Этот режим можно использовать только совместно с режимом доступа FileAccess.Write. При попытке чтения из файла, открытого подобным образом, возникает исключение ArgumentException | |
Create |
ОС должна создать новый файл. Если указанный файл уже существует, он будет перезаписан | |
CreateNew |
ОС должна создать новый файл. Если указанный файл уже существует, возникнет исключение IOException | |
Open |
Требуется открыть существующий файл. Необходим доступ FilelOPerraissionAccess.Read. Если требуемый файл не найден, возникает исключениеSystem.FileNotFoundException | |
OpenOrCreate |
Если указанный файл существует, он должен быть открыт. В противном случае ОС должна создать и открыть указанный файл | |
Truncate |
Требуется открыть существующий файл. После открытия файл обрезается до нулевой длины, при этом все ранее хранившиеся в нем данные пропадают. При попытке чтения из файла, открытого подобным образом, возникает исключение |
В зависимости от того, для какой цели создается файл, вы можете выбрать тот или иной режим открытия потока. Например, если поток, связанный с файлом, открывается только для чтения, выбирайте режим FileMode.Open. В этом случае будет открыт существующий файл. Если же файл открывается для записи, то вы можете либо открыть существующий файл, перезаписав его содержимое или дописав в него новые данные, а также создать новый файл.
В классе FileStreamсуществует несколько конструкторов, позволяющих определить не только путь к файлу, но и режим его открытия, разрешенный доступ к файлу и режим совместного использования файла:
FileStream fs = new FileStream(name, FileMode.Open, FileAccess.Read);
FileStream fsl = new FileStream(name, FileMode.Open, FileAccess.Read, FileShare.Read);
Остановимся на режиме доступа к файлу, передаваемом приведенным выше конструкторам через третий параметр (табл. 4.2). Режим доступа задается как статическая константа класса FileAccess.
Таблица 4.2 - Режимы доступа FileAccess
Режим |
Тип доступа |
Read |
Доступ только на чтение |
ReadWrite |
Доступ на чтение и запись |
Write |
Доступ на запись |
При необходимости программа может задать режим совместного использования файла, когда для одного и того же файла одновременно создается несколько потоков. Этот режим задается при помощи статических констант класса FileShare(табл. 4.3).
Таблица 4.3 - Режимы совместного использования файла FileShare
Режим |
Тип доступа |
Inheritable |
Идентификатор файла может наследоваться дочерним процессом |
None |
Запрет совместного использования файла. Любые дополнительные запросы на открытие файла будут запрещены то тех пор, пока файл не будет закрыт |
Read |
Допускаются дополнительные запросы на открытие файла для чтения |
ReadWrite |
Допускаются дополнительные запросы на чтение и запись |
Write |
Допускаются дополнительные запросы на запись |
Открытие потоков Binary Writer и BinaryReader
Итак, ваша программа создала поток на базе файла, воспользовавшись для этого классом FileStream. Далее на базе полученного таким образом потока необходимо создать потоки классовBinaryWriterиBinaryReader, предназначенные соответственно для записи в файл и чтения из файла двоичных данных;
BinaryWriter bw = new BinaryWriter(fs); BinaryReader br = new BinaryReader(fs);
Закрытие потоков
После того как программа завершила работу с потоками, она должна их закрыть.
Для закрытия потоков используйте метод Close. Закрывайте потоки в порядке, обратном открытию. Если вы вначале открыли потокFileStream, а затем создали на его базе потоки классаBinaryWriterиBinaryReader, то закрывать потоки нужно в обратном порядке: вначале закройте потокиBinaryWriterиBinaryReader, а затем потокFileStream:
FileStream fs = new FileStream("myfile.datн, FileMode.CreateNew);
BinaryWriter bw = new BinaryWriter(fs);
BinaryReader br = new BinaryReader(fs);
// Работа с потоками
bw.Close();
br.Close();
fs.Close();
Запись двоичных данных
Для записи двоичных данных в поток BinaryWriterпредусмотрено несколько перегруженных методовWrite, приведенных ниже:
public virtual void Write(bool);
public virtual void Write(byte);
public virtual void Write(byte[]);
public virtual void Write(char);
public virtual void Write(char[]);
public virtual void Write(decimal);
public virtual void Write(double);
public virtual void Write(short);
public virtual void Write(int);
public virtual void Write(long);
public virtual void Write(sbyte);
public virtual void Write(float);
public virtual void Write(uint);
public virtual void Write(ulong);
public virtual void Write(string);
public virtual void Write(byte[], int, int);
public virtual void Write(char[], int, int) ,-
Способ применения большинства перечисленных методов интуитивно ясен: для записи данных того или иного типа в файл вам нужно передать ссылку на экземпляр данных в качестве параметра методу Write. В зависимости от типа данных компилятор выберет нужную перегруженную версию этого метода.
При записи в двоичный поток текстовой строки stringона будет предваряться префиксом, содержащим значение длины строки. Строка будет записана в кодировкеASCII.
Последние два перегруженных метода Writeпозволяют записать в поток массив соответственно двоичных байтов и символовUNICODE. Второй параметр метода задает начальный индекс блока данных в массиве, а третий — размер блока (соответственно в байтах и символах).
Чтение двоичных данных
Чтобы прочитать данные из потока BinaryReader, нужно использовать один из методов, специально предусмотренных для этого в классеBinaryReader. Мы привели краткий список этих методов в табл. 4.4.
Таблица 4.4 - Методы для чтения данных класса BinaryReader
Метод |
Тип данных, считываемых из потока |
ReadBoolean |
Один объект типа Boolean |
ReadByte |
1 байт данных |
ReadBytes |
Чтение заданного количества байтов данных |
ReadChar |
Один текстовый символ |
ReadChars |
Чтение заданного количества текстовых символов |
ReadDecimal |
Десятичное значение размером 16 байт |
ReadSingle |
Значение с плавающей десятичной точкой размером 4 байта |
ReadDouble |
Значение с плавающей десятичной точкой размером 8 байт |
ReadSByte |
Число со знаком размером 1 байт |
Readlntl6 |
Число со знаком размером 2 байта |
Readlnt32 |
Число со знаком размером 4 байта |
Readlnt64 |
Число со знаком размером 8 байт |
ReadUIntl6 |
Число без знака размером 2 байта |
ReadUInt32 |
Число без знака размером 4 байта |
ReadUInt64 |
Число без знака размером 8 байт |
ReadString |
Текстовая строка с префиксом длины |