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);
Читать байты до конца файла,
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)
В методе Write() предпринимается попытка записать в файл количество count байтов из массива array, начиная с элемента array[offset]. Он возвращает количество байтов, успешно записанных в файл. Если во время записи возникает ошибка, то генерируется исключение IOException. А если базовый поток не открывается для вывода, то генерируется исключение NotSupportedException. Кроме того, может быть сгенерирован ряд других исключений.
Вам, вероятно, известно, что при выводе в файл выводимые данные зачастую записываются на конкретном физическом устройстве не сразу. Вместо этого они буферизуются на уровне операционной системы до тех пор, пока не накопится достаточный объем данных, чтобы записать их сразу одним блоком. Благодаря этому повышается эффективность системы. Так, на диске файлы организованы по секторам величиной от 128 байтов и более. Поэтому выводимые данные обычно буферизуются до тех пор, пока не появится возможность записать на диск сразу весь сектор. .
Но если данные требуется записать на физическое устройство без предварительного накопления в буфере, то для этой цели можно вызвать метод 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 c = 'А'; c <= 'Z'; c++) fout.WriteByte((byte) c);
} catch(IOException exc) {
Console.WriteLine ("Ошибка ввода-вывода: \n" + exc.Message) ;
} finally {
if(fout != null) fout.Close();
}
}
}
В данной программе сначала создается выходной файл под названием test.txt с помощью перечисляемого значения FileMode.CreateNew. Это означает, что файл с таким же именем не должен уже существовать. (В противном случае генерируется исключение IOException.) После открытия выходного файла в него записываются
прописные буквы английского алфавита. По завершении данной программы содержимое файла test.txt оказывается следующим.
ABCDEFGHIJKLMNOPQRSTUVWXYZ
Дата добавления: 2019-02-12; просмотров: 363; Мы поможем в написании вашей работы! |
Мы поможем в написании ваших работ!