Г. Шилдт - Полный справочник по C# (1160789), страница 71
Текст из файла (страница 71)
Таким образом,файловые операции чтения и записи с использованием байтовых потоков очень востребованы. С# также позволяет поместить файловый поток с ориентацией на побайтовую обработку в символьный объект. Файловые операции, .ориентированные насимволы, используются в случае текстовых файлов. Символьные потоки рассматриваются ниже в этой главе. А пока изучим ввод-вывод данных на побайтовой основе.Чтобы создать байтовый поток с привязкой к файлу, используйте классFileStream. Класс FileStream — производный от Stream и потому обладает функциональными возможностями базового класса. Помните, что потоковые классы, включая FileStream, определены в пространстве имен System.
10. Следовательно, при ихиспользовании в начало программы вы должны включить следующую инструкцию:1 u s i n g System.10;Как открыть и закрыть файлЧтобы создать байтовый поток, связанный с файлом, создайте объект классаFileStream. В классе FileStream определено несколько конструкторов. Чаще всегоиз них используется следующий:F i l e S t r e a m ( s t r i n g filename,FileMode mode)Здесь элемент filename означает имя файла, который необходимо открыть, причем оно может включать полный путь к файлу. Элемент mode означает, как именнодолжен быть открыт этот файл, или режим открытия.
Элемент mode может приниматьодно из значений, определенных перечислением FileMode (они описаны в табл. 14.4).Этот конструктор открывает файл для доступа с разрешением чтения и записи.Таблица 14.4. Значения перечисления F i l e M o d eЗначениеОписаниеF i l e M o d e . AppendДобавляет выходные данные в конец файлаFileMode. CreateСоздает новый выходной файл. Существующий файл с таким же именем будетF i l e M o d e .
CreateNewСоздает новый выходной файл. Файл с таким же именем не должен существоватьF i l e M o d e . OpenОткрывает существующий файлFileMode. openOrCreateОткрывает файл, если он существует. В противном случае создает новыйFileMode. TruncateОткрывает существующий файл, но усекает его длину до нуляразрушенГлава 14. Использование средств ввода-вывода383Если попытка открыть файл оказалось неуспешной, генерируется исключение. Еслифайл невозможно открыть по причине его отсутствия, генерируется исключение типаFileNotFoundException.
Если файл невозможно открыть из-за ошибки ввода-вывода,генерируется исключение типа lOException. Возможны также исключения следующихтипов: ArgumentNullException (если имя файла представляет собой null-значение),ArgumentException (если некорректен параметр mode), SecurityException (еслипользователь не обладает правами доступа) и DirectoryNotFoundException (еслинекорректно задан каталог).В следующем фрагменте программы показан один из способов открыть файлt e s t . dat для ввода данных.FileStream f i n ;try {fin = new FileStream("test.dat", FileMode.Open);}catch(FileNotFoundException exc) {Console.WriteLine(exc.Message) ;return;}catch {Console.WriteLine("He удается открыть файл.");return;}Здесь первая catch-инструкция перехватывает ошибку, связанную с отсутствиемфайла. Вторая, предназначенная для "всеобщего перехвата", обрабатывает другиеошибки, которые возможны при работе с файлами.
Конечно, можно было бы отслеживать возникновение каждой ошибки в отдельности, сообщая о возникшей проблеме. Но ради простоты во всех примерах этой книги организован перехват исключенийтолько типа FileNotFoundException или lOException, но в реальных приложениях(в зависимости от обстоятельств) вам, скорее всего, придется обрабатывать другиевозможные исключения.Как уже упоминалось, приведенный выше конструктор FileStream открываетфайл с доступом для чтения и записи. Если необходимо ограничить доступ толькочтением или только записью, используйте следующий конструктор:FileStream(string filename, FileMode mode,FileAccess how)Как и прежде, элемент filename означает имя открываемого файла, a mode —способ его открытия.
Значение, передаваемое с помощью параметра how, определяетспособ доступа к файлу. Этот параметр может принимать одно из значений, определенных перечислением FileAccess, а именно:FileAccess.ReadFileAccess.WriteFileAccess.ReadWriteНапример, при выполнении следующей инструкции файл t e s t . d a t будет открыттолько для чтения:FileStream f i n = new F i l e S t r e a m ( " t e s t .
d a t " , FileMode.Open,FileAccess.Read);По завершении работы с файлом его необходимо закрыть. Для этого достаточновызвать метод Close (). Его общая форма вызова имеет такой вид:void Close()При закрытии файла освобождаются системные ресурсы, ранее выделенные дляэтого файла, что дает возможность использовать их для других файлов. МетодClose () может генерировать исключение типа lOException.384Часть I. Язык С#Считывание байтов из объекта класса Files treamВ классе FileStream определены два метода, которые считывают байты из файла:ReadByteO и Read (). Чтобы прочитать из файла один байт, используйте методReadByte ( ) , общая форма вызова которого имеет следующий вид:int ReadByte()При каждом вызове этого метода из файла считывается один байт, и метод возвращает его как целочисленное значение. При обнаружении конца файла метод возвращает —1.
Метод может генерировать исключения типов NotSupportedExeption(поток не открыт для ввода) и ObjectDisposedException (поток закрыт).Чтобы считать блок байтов, используйте метод Read (), общая форма вызова которого такова:i n t Read(byte[] buf, i n t offset,i n t numBytes)Метод Read () пытается считать numBytes байтов в массив buf, начиная с элемента buf [off set]. Он возвращает количество успешно считанных байтов.
При возникновении ошибки ввода-вывода генерируется исключение типа lOException. Помимопрочих, возможно также генерирование исключения типа NotSupportedException,если используемый поток не поддерживает операцию считывания данных.В следующей программе метод ReadByte () используется для ввода содержимоготекстового файла и его отображения. Имя файла задается в качестве аргумента командной строки. Обратите внимание на try/catch-блоки, которые обрабатывают двеошибки, возможные при первоначальном выполнении этой программы: "указанныйфайл не найден" или "пользователь забыл указать имя файла".
Такой подход обычнополезен при использовании аргументов командной строки./* Отображение содержимого текстового файла.Чтобы использовать эту программу, укажите имяфайла, содержимое которого вы хотите увидеть.Например, чтобы увидеть содержимое файла TEST.CS,используйте следующую командную строку:ShowFile TEST.CS*/using System;using System.10;class ShowFile {public s t a t i c void Main(string[] args) {inti;FileStreamfin;try {fin = new FileStream(args[0], FileMode.Open);} catch(FileNotFoundException exc) {Console.WriteLine(exc.Message) ;return;} catch(IndexOutOfRangeException exc) {Console.WriteLine(exc.Message +"ХпПрименение: ShowFile Файл");return;Глава 14.
Использование средств ввода-вывода385// Считываем байты до тех пор, пока не встретится EOF.do {try {i = fin.ReadByte();} catch(Exception exc) {Console.WriteLine(exc.Message);return;}if(i != -1) Console.Write((char) i ) ;} while(i != - 1 ) ;fin.Close();Запись данных в файлЧтобы записать байт в файл, используйте метод WriteByte (). Простейшая егоформа имеет следующий вид:void WriteByte(byte val)Этот метод записывает в файл байт, заданный параметром val. При возникновении во время записи ошибки генерируется исключение типа lOException.
Если соответствующий поток не открыт для вывода данных, генерируется исключение типаNotSupportedException.С помощью метода Write О можно записать в файл массив байтов. Это делаетсяследующим образом:void Write(byte[] buf, int offset, int numBytes)Метод Write () записывает в файл numBytes байтов из массива buf, начиная сэлемента buf [ o f f s e t ] . При возникновении во время записи ошибки генерируетсяисключение типа lOException. Если соответствующий поток не открыт для выводаданных, генерируется исключение типа NotSupportedException. Возможны и другие исключения.Вероятно, вы уже знаете, что при выполнении операции вывода в файл выводимыеданные зачастую не записываются немедленно на реальное физическое устройство, абуферизируются операционной системой до тех пор, пока не накопится порция данных достаточного размера, чтобы ее можно было всю сразу переписать на диск.