Программирование >>  Обработка исключительных ситуаций 

1 ... 80 81 82 [ 83 ] 84 85 86 ... 142


Результат работы программы: 100 01234 56789 10 98760000

Текущая позиция в потоке 7

Текущая позиция в потоке первоначально устанавливается на начало файла (для любого режима открытия, кроме Append) и сдвигается на одну позицию при записи каждого байта.

Для установки желаемой позиции чтения используется метод Seek, имеющий два параметра: первый задает смещение в байтах относительно точки отсчета, задаваемой вторым. Точки отсчета задаются константами перечисления SeekOrigin: начало файла - Begin, текущая позиция - Current и конец файла - End.

В данном примере файл создавался в текущем каталоге. Можно указать и полный путь к файлу, при этом удобнее использовать дословные литералы, речь о которых шла в разделе Литералы (см. с. 30), например:

FileStream f = new FileStreamC @ D:\CJ\test.txt .

FileMode.Create, FileAccess.ReadWrite ):

В дословных литералах не требуется дублировать обратную косую черту.

Операции по открытию файлов могут завершиться неудачно, например, при ошибке в имени существующего файла или при отсутствии свободного места на диске, поэтому рекомендуется всегда контролировать результаты этих операций.

В случае непредвиденных ситуаций среда выполнения генерирует различные исключения, обработку которых следует предусмотреть в программе, например:

FileNotFoundException, если файла с указанным именем в указанном каталоге не существует;

DirectoryNotFoundException, если не существует указанный каталог;

Argument Except ion, если неверно задан режим открытия файла;

IOException, если файл не открывается из-за ошибок ввода-вывода. Возможны и другие исключительные ситуации.

Удобно обрабатывать наиболее вероятные ошибки раздельно, чтобы предоставить пользователю программы в выводимом сообщении наиболее точную информацию. В приведенном далее примере отдельно перехватывается ошибка в имени файла, а затем обрабатываются все остальные возможные ошибки:

FileStream f = new FileStreamC @ d:\C#\test.tx , Fi1eMode.Open. FileAccess.Read );

действия с файлом

f.CloseO;

catchC FileNotFoundException e )



Асинхронный ввод-вывод 253

Console.WriteLineC е.Message );

Console.WriteLineC Проверьте правильность itii файла! ); return;

catch( Exception e )

Console.WriteLineC Error: + e.Message ); return;

При закрытии файла освобождаются все связанные с ним ресурсы, например, для файла, открытого для записи, в файл выгружается содержимое буфера. Поэтому рекомендуется всегда закрывать файлы после окончания работы, в особенности файлы, открытые для записи. Если буфер требуется выгрузить, не закрывая файл, используется метод Flush.

Асинхронный ввод-вывод

Класс Stream (и, соответственно, FileStream) поддерживает два способа выполнения операций ввода-вывода: синхронный и асинхронный. По умолчанию файлы открываются в синхронном режиме, то есть последующие операторы выполняются только после завершения операций ввода-вывода. Для длительных файловых операций более эффективно выполнять ввод-вывод асинхронно, в отдельном потоке выполнения . При этом в первичном потоке можно выполнять другие операции.

Для асинхронного ввода-вывода необходимо открыть файл в асинхронном режиме, для этого используется соответствующий вариант перегруженного конструктора. Асинхронная операция ввода инициируется с помощью метода BeginRead. Помимо характеристик буфера, в который выполняется ввод, в этот метод передается делегат, задающий метод, выполняемый после завершения ввода.

Этот метод может инициировать обработку полученной информации, возобновить операцию чтения или выполнить любые другие действия, например, проверить успешность ввода и сообщить о его завершении. Обычно в этом методе вызывается метод EndRead, который завершает асинхронную операцию.

Аналогично выполняется и асинхронный вывод. В листинге 11.2 приведен пример асинхронного чтения из файла большого объема и параллельного выполнения диалога с пользователем.

ПРИМЕЧАНИЕ-

Вообще говоря, существуют различные способы завершения асинхронных операций, и здесь демонстрируется только один из них.

1 Работа с потоками в1полнения рассматривалась в пред1дущей главе.



Листинг 11.2. Асинхронный ввод

using System; using System.10; using System.Threading;

namespace ConsoleApplicationl

class Demo

public void UserlnputO

диалог с пользователем

string s;

{ Console.WriteLineC Введите строку. Enter для завершения );

s = Console.ReadLineO; } while (s.Length != 0 );

public void OnCompletedReadC IAsyncResult ar )

. 1

int bytes = f.EndRead( ar ); Console.WriteLineC Считано + bytes );

public void AsyncReadO

f = new FileStreamC D:\\verybigfile . FileMode.Open.

FileAccess.Read, FileShare.Read. buf.Length, true ); III

callback = new AsyncCallbackC OnCompletedRead ): 1/3

f.BeginReadC buf, 0. buf.Length, callback, null ); 4

FileStream f;

byte[] buf = new byte[66666666]; AsyncCallback callback;

class Program

{ static void MainO

Demo d = new DemoO; d. AsyncReadO; d.UserlnputO;



1 ... 80 81 82 [ 83 ] 84 85 86 ... 142

© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки.
Яндекс.Метрика