Шрифт:
Но если данные требуется записать на физическое устройство без предварительно го накопления в буфере, то для этой цели можно вызвать метод Flush. void Flush
При неудачном исходе данной операции генерируется исключение IOException. Если же поток закрыт, то генерируется исключение ObjectDisposedException.
По завершении вывода в файл следует закрыть его с помощью метода Close. Этим гарантируется, что любые выведенные данные, оставшиеся в дисковом буфе ре, будут записаны на диск. В этом случае отпадает необходимость вызывать метод Flush перед закрытием файла.
Ниже приведен простой пример программы, в котором демонстрируется порядок записи данных в файл. // Записать данные в файл. using System; using System.IO; class WriteToFile { static void Main(string[] args) { FileStream fout = null; try { // Открыть выходной файл. fout = new FileStream("test.txt", FileMode.CreateNew); // Записать весь английский алфавит в файл. for(char с = 'А'; с <= 'Z'; C++) fout.WriteByte((byte) с); } catch(IOException exc) { Console.WriteLine("Ошибка ввода-вывода:\n" + exc.Message); } finally { if (fout != null) fout.Close; } } }
В данной программе сначала создается выходной файл под названием test.txt с помощью перечисляемого значения FileMode.CreateNew. Это означает, что файл с таким же именем не должен уже существовать. (В противном случае генерируется исключение IOException.) После открытия выходного файла в него записываются прописные буквы английского алфавита. По завершении данной программы содер жимое файла test.txt оказывается следующим. ABCDEFGHIJKLMNOPQRSTUVWXYZ Использование класса FileStream для копирования файла
Преимущество байтового ввода-вывода средствами класса FileStream заключает ся, в частности, в том, что его можно применить к файлам практически любого типа, а не только к текстовым файлам. В качестве примера ниже приведена программа, по зволяющая копировать файл любого типа, в том числе исполняемый. Имена исходно го и выходного файлов указываются в командной строке. /* Копировать файл. Чтобы воспользоваться этой программой, укажите имена исходного и выходного файлов. Например, для копирования файла FIRST.DAT в файл SECOND.DAT введите в командной строке следующее: CopyFile FIRST.DAT SECOND.DAT */ using System; using System.IO; class CopyFile { static void Main(string[] args) { int i; FileStream fin = null; FileStream fout = null; if(args.Length != 2) { Console.WriteLine("Применение: CopyFile Откуда Куда"); return; } try { // Открыть файлы. fin = new FileStream(args[0], FileMode.Open); fout = new FileStream(args[1], FileMode.Create); // Скопировать файл. do { i = fin.ReadByte; if(i != -1) fout.WriteByte((byte)i); } while (i != —1); } catch(IOException exc) { Console.WriteLine("Ошибка ввода-вывода:\n" + exc.Message); } finally { if(fin != null) fin.Close; if(fout != null) fout.Close; } } } Символьный ввод-вывод в файл
Несмотря на то что файлы часто обрабатываются побайтово, для этой цели можно воспользоваться также символьными потоками. Преимущество символьных потоков заключается в том, что они оперируют символами непосредственно в уникоде. Так, если требуется сохранить текст в уникоде, то для этого лучше всего подойдут именно символьные потоки. В целом, для выполнения операций символьного ввода-вывода в файлы объект класса FileStream заключается в оболочку класса StreamReader или StreamWriter. В этих классах выполняется автоматическое преобразование байтового потока в символьный и наоборот.
Не следует, однако, забывать, что на уровне операционной системы файл представ ляет собой набор байтов. И применение класса StreamReader или StreamWriter никак не может этого изменить.
Класс StreamWriter является производным от класса TextWriter, а класс StreamReader — производным от класса TextReader. Следовательно, в классах StreamReader и StreamWriter доступны методы и свойства, определенные в их ба зовых классах. Применение класса StreamWriter
Для создания символьного потока вывода достаточно заключить объект клас са Stream, например FileStream, в оболочку класса StreamWriter. В классе StreamWriter определено несколько конструкторов. Ниже приведен едва ли не са мый распространенный среди них: StreamWriter(Stream поток)
где поток обозначает имя открытого потока. Этот конструктор генерирует исклю чение ArgumentException, если поток не открыт для вывода, а также исключение ArgumentNullException, если поток оказывается пустым. После создания объекта класс StreamWriter выполняет автоматическое преобразование символов в байты.
Ниже приведен простой пример сервисной программы ввода с клавиатуры и выво да на диск набранных текстовых строк, сохраняемых в файле test.txt. Набираемый тест вводится до тех пор, пока в нем не встретится строка "стоп". Для символьного вы вода в файл в этой программе используется объект класса FileStream, заключенный в оболочку класса StreamWriter. // Простая сервисная программа ввода с клавиатуры и вывода на диск, // демонстрирующая применение класса StreamWriter. using System; using System.IO; class KtoD { static void Main { string str; FileStream fout; // Открыть сначала поток файлового ввода-вывода. try { fout = new FileStream("test.txt", FileMode.Create); } catch(IOException exc) { Console.WriteLine("Ошибка открытия файла:\n" + exc.Message); return; } // Заключить поток файлового ввода-вывода в оболочку класса StreamWriter. StreamWriter fstr_out = new StreamWriter(fout); try { Console.WriteLine("Введите текст, а по окончании — 'стоп'."); do { Console.Write(": "); str = Console.ReadLine; if(str != "стоп") { str = str + "\r\n"; // добавить новую строку fstr_out.Write(str); } } while(str != "стоп"); } catch(IOException exc) { Console.WriteLine("Ошибка ввода-вывода:\n" + exc.Message); } finally { fstr_out.Close ; } } }
В некоторых случаях файл удобнее открывать средствами самого класса StreamWriter. Для этого служит один из следующих конструкторов: StreamWriter(string путь) StreamWriter(string путь, bool append)
где путь — это имя открываемого файла, включая полный путь к нему. Если во вто рой форме этого конструктора значение параметра append равно true, то выводи мые данные присоединяются в конец существующего файла. В противном случае эти данные перезаписывают содержимое указанного файла. Но независимо от формы конструктора файл создается, если он не существует. При появлении ошибок ввода- вывода в обоих случаях генерируется исключение IOException. Кроме того, могут быть сгенерированы и другие исключения.