Полное руководство. С# 4.0 - Шилдт Герберт
Шрифт:
Интервал:
Закладка:
Но если данные требуется записать на физическое устройство без предварительного накопления в буфере, то для этой цели можно вызвать метод 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 + "rn"; // добавить новую строку 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. Кроме того, могутбыть сгенерированы и другие исключения.
Ниже приведен вариант представленной ранее сервисной программы ввода с клавиатуры и вывода на диск, измененный таким образом, чтобы открывать выходнойфайл средствами самого класса StreamWriter.// Открыть файл средствами класса StreamWriter.using System;using System.IO;class KtoD { static void Main() { string str; StreamWriter fstr_out = null; try { // Открыть файл, заключенный в оболочку класса StreamWriter. fstr_out = new StreamWriter("test.txt"); Console.WriteLine("Введите текст, а по окончании — 'стоп'."); do { Console.Write(" : "); str = Console.ReadLine(); if(str != "стоп") { str = str + "rn"; // добавить новую строку fstr_out.Write(str); } } while(str != "стоп"); } catch(IOException exc) { Console.WriteLine("Ошибка ввода-вывода:n" + exc.Message); } finally { if(fstr_out != null) fstr_out.Close(); } }}Применение класса StreamReader
Для создания символьного потока ввода достаточно заключить байтовый поток воболочку класса StreamReader. В классе StreamReader определено несколько конструкторов. Ниже приведен наиболее часто используемый конструктор:StreamReader(Stream поток)
где поток обозначает имя открытого потока. Этот конструктор генерирует исключение ArgumentNullException, если поток оказывается пустым, а также исключениеArgumentException, если поток не открыт для ввода. После своего создания объекткласса StreamReader выполняет автоматическое преобразование байтов в символы.По завершении ввода из потока типа StreamReader его нужно закрыть. При этом закрывается и базовый поток.