C# 4.0 полное руководство - 2011
Шрифт:
Для чтения блока байтов из файла служит метод Read , общая форма которого выглядит так.
int Read(byte[ ] array, int offset, int count)
В методе Read предпринимается попытка считать количество count байтов в массив array, начиная с элемента array[offset]. Он возвращает количество
В приведенном ниже примере программы метод ReadByte используется для ввода и отображения содержимого текстового файла, имя которого указывается в качестве аргумента командной строки. Обратите внимание на то, что в этой программе проверяется, указано ли имя файла, прежде чем пытаться открыть его.
/* Отобразить содержимое текстового файла.
Чтобы воспользоваться этой программой, укажите имя того файла, содержимое которого требуется отобразить. Например, для просмотра содержимого файла TEST.CS введите в командной строке следующее:
ShowFile TEST.CS
*/
using System; using System.10;
class ShowFile {
static void Main(string[] args) { int i;
FileStream fin; if(args.Length != 1) {
Console.WriteLine("Применение: ShowFile Файл"); return;
}
try {
fin = new FileStream(args[0], FileMode.Open);
} catch(IOException exc) {
Console!WriteLine("He удается открыть файл");
Console.WriteLine(exc.Message);
return; // Файл не открывается, завершить программу
}
// Читать байты до конца файла, try {
• do {
i = fin.ReadByte;
if(i != -1) Console.Write((char) i);
} while(i != -1);
} catch(IOException exc) {
Console.WriteLine("Ошибка чтения файла");
Console.WriteLine(exc.Message) ;
} finally { fin.Close ;
}
}
}
Обратите внимание на то, что в приведенной выше программе применяются два блока try. В первом из них перехватываются исключения, возникающие при вводе-выводе и способные воспрепятствовать открытию файла. Если произойдет ошибка ввода-вывода, выполнение программы завершится. В противном случае во втором блоке try будет продолжен контроль исключений, возникающих в операциях ввода-вывода. Следовательно, второй блок try выполняется только в том случае, если в переменной fin содержится ссылка на открытый файл. Обратите также внимание на то, что файл закрывается в блоке finally, связанном со вторым блоком try. Это означает, что независимо от того, как завершится цикл do-while (нормально или аварийно из-за ошибки), файл все равно будет закрыт. И хотя в данном конкретном примере это и так важно, поскольку программа все равно завершится в данной точке, преимущество такого подхода, вообще говоря,
В некоторых случаях оказывается проще заключить те части программы, где осуществляется открытие и доступ к файлу, внутрь блока try, вместо того чтобы разделять обе эти операции. В качестве примера ниже приведен другой, более краткий вариант написания представленной выше программы ShowFile.
// Отобразить содержимое текстового файла.
using System; using System.10;
class ShowFile {
static void Main(string[] args) { int i;
FileStream fin = null;
if (args.Length != 1)' {
Console.WriteLine("Применение: ShowFile File"); return;
}
try {
fin = new FileStream(args[0], FileMode.Open);
// Читать байты до конца файла, do {
i = fin.ReadByte;
if(i != -1) Console.Write((char) i);
} while (i != -1);
} catch(IOException exc) {
Console.WriteLine("Ошибка ввода-вывода:\n" + exc.Message);
} finally {
if(fin != null) fin.Close;
}
}
}
Обратите внимание на то, что в данном варианте программы переменная fin ссылки на объект класса FileStream инициализируется пустым значением. Если файл удастся открыть в конструкторе класса FileStream, то значение переменной fin окажется непустым, а иначе — оно так и останется пустым. Это очень важно, поскольку метод Close вызывается внутри блока finally только в том случае, если значение переменной fin оказывается непустым. Подобный механизм препятствует любой попытке вызвать метод С lose для переменной fin, когда она не ссылается на открытый файл. Благодаря своей компактности такой подход часто применяется во многих примерах организации ввода-вывода, приведенных далее в этой книге. Следует, однако, иметь в виду, что он не пригоден в тех случаях, когда ситуацию, возникающую в связи с невозможностью открыть файл, нужно обрабатывать отдельно. Так, если пользователь неправильно введет имя файла, то на экран, возможно, придется вывести приглашение правильно ввести имя файла, прежде чем входить в блок try, где осуществляется проверка правильности доступа к файлу.
В целом, порядок открытия, доступа и закрытия файла зависит от конкретного приложения. То, что хорошо в одном случае, может оказаться неприемлемым в другом. Поэтому данный процесс приходится приспосабливать к конкретным потребностям разрабатываемой программы.
Запись в файл
Для записи байта в файл служит метод WriteByte. Ниже приведена его простейшая форма.
void WriteByte(byte value)
Этот метод выполняет запись в файл байта, обозначаемого параметром value. Если базовый поток не открывается для вывода, то генерируется исключение NotSupportedException. А если поток закрыт, то генерируется исключение ObjectDisposedException.
Для записи в файл целого массива байтов может быть вызван метод Write О. Ниже приведена его общая форма.
void Write(byte[] array, int offset, int count)