Для чтения блока байтов из файла служит метод Read(), общая форма которого выглядит так.
int Read(byte[ ] array, int offset, int count)
В методе Read()предпринимается попытка считать количество count байтов в массив array, начиная с элемента array[offset]. Он возвращает количество байтов, успешно считанных из файла. Если же возникает ошибка ввода-вывода, то генерируется исключение IOException. К числу других вероятных исключений, которые генерируются при этом, относится NotSupportedException. Это исключение генерируется в том случае, если чтение из файла не поддерживается в потоке.
В приведенном ниже примере программы метод ReadByte()используется для ввода и отображения содержимого текстового файла, имя которого указывается в качестве аргумента командной строки. Обратите внимание на то, что в этой программе проверяется, указано ли имя файла, прежде чем пытаться открыть его.
/* Отобразить содержимое текстового файла.
Чтобы воспользоваться этой программой, укажите имя того файла, содержимое которого требуется отобразить. Например, для просмотра содержимого файла TEST.CS введите в командной строке следующее:
ShowFile TEST.CS
*/
using System;
using System.IO;
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(нормально или аварийно из-за ошибки), файл все равно будет закрыт. И хотя в данном конкретном примере это и так важно, поскольку программа все равно завершится в данной точке, преимущество такого подхода, вообще говоря, заключается в том, что файл закрывается в завершающем блоке finallyв любом случае — даже если выполнение кода доступа к этому файлу завершается преждевременно из-за какого-нибудь исключения.
В некоторых случаях оказывается проще заключить те части программы, где осуществляется открытие и доступ к файлу, внутрь блока try, вместо того чтобы разделять обе эти операции. В качестве примера ниже приведен другой, более краткий вариант написания представленной выше программы ShowFile.
// Отобразить содержимое текстового файла.
using System;
using System.IO;
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);
// Читать байты до конца файла,
Читать дальше