
Лабораторные работы по информатике для специальности «Моделирование и исследование операций в организационно-технических системах»
Лабораторная работа №12 Структурированная обработка ошибок.
Введение
В лабораторной работе рассмотрен механизм обработки исключительных ситуаций, синтаксис описания защищенных блоков. Приведены примеры программ использующих защищенные блоки.
Механизм обработки исключительных ситуаций
Защищенные блоки
Для обработки исключительных ситуаций в Object Pascal предусмотрен механизм защищенных блоков. Защищенный блок начинается зарезервированным словом try (попытаться выполнить) и завершается словом end. В Object Pasсal существует два вида защищенных блоков: блок except (исключить) и блок finally (завершить). Каждый из видов защищенных блоков подробно рассматривается ниже.
Блок завершения
Синтаксис этого защищенного блока имеет следующий вид try
<операторы> finally
<операторы> end;
Если при выполнении операторов в секции try finally не произошло ошибок, то далее выполняются операторы секции finally end. Если при выполнении операторов в секции try finally в каком-либо из операторов произошла ошибка, то пропускаются все операторы начиная с ошибочного и начинают выполняться операторы секции finally end. Иными словами, операторы в секции finally end выполняются всегда (рисунок 1).

Лабораторные работы по информатике для специальности «Моделирование и исследование операций в организационно-технических системах»
Рисунок 1 – Логика работы блока завершения
Защищенные блоки этого вида применяют для корректного освобождения ресурсов. Например, если при работе с файлом произошла какая-либо ошибка, то его необходимо закрыть. Если ошибок не было, то при завершении работы файл все равно надо закрыть. Модернизируем программу осуществляющую копирование файлов приведенную в лабораторной работе № 11, добавим обработку ошибок.
Листинг 1 – Копирование файлов
program CopyFile;
{$APPTYPE CONSOLE} |
|
uses SysUtils, Classes; |
|
var Srm1, |
//входной поток |
Srm2:TFileStream; |
//выходной поток |
SourceFileName, |
//имя входного файла |
DestFileName:string; //имя файла копии begin
//открываем файл источник данных write('Source file >> '); readln(SourceFileName);
try //в этом блоке может произойти ошибка
//создаем поток в режиме только для чтения
Srm1:=TFileStream.Create(SourceFileName, fmOpenRead);
//создаем файл приемник write('Destination file >> '); readln(DestFileName);
//создаем поток в режиме создания нового потока
Srm2:=TFileStream.Create(DestFileName, fmCreate);
//копирование содержимого потока Srm1 в Srm2 Srm2.CopyFrom(Srm1, Srm1.Size); writeln('File success copy');

Лабораторные работы по информатике для специальности «Моделирование и исследование операций в организационно-технических системах»
finally
//уничтожение объектов
Srm1.Free;
Srm2.Free;
end;
writeln('Press Enter to exit'); readln;
end.
Блок исключения
Блок исключения имеет следующий синтаксис try
<операторы> except
<обработчики исключений> else
<операторы> end;
Логика работы этого блока следующая. Если при выполнении операторов секции try except не было ошибок, то операторы в секции except end пропускаются. Если при выполнении секции try except происходит ошибка, то выполнении операторов этой секции прерывается, начиная с оператора вызвавшего ошибку и начинают выполняться операторы секции except end (рисунок 2).
Рисунок 2 – Работа блока исключения
В секции except end располагаются обработчики исключений имеющие следующий синтаксис
on <класс исключения> do <оператор>;

Лабораторные работы по информатике для специальности «Моделирование и исследование операций в организационно-технических системах»
где on, do – зарезервированные слова;
<класс исключения> – класс обработки исключения.
Имя класса служит ключом выбора, а обработка исключения производится оператором стоящим после слова do. Поиск нужного обработчика осуществляется с начала списка вниз до тех пор пока не встретится класс способный обрабатывать исключение данного типа. Если подходящего класса не встретится, то управление передается операторам, стоящим за else.Если тип и причина возникновения ошибки не существенны, то можно в секции except end вообще не указывать обработчики исключений, а сразу вставить код реакции на ошибку, например
try
...
except
...
writeln(‘Fatal Error’)
...
end;
Защищенные блоки могут вкладываться друг в друга на нограниченуую глубину. Модифицируем программу приведенную в листинге 1
Листинг 2
program CopyFile2;
{$APPTYPE CONSOLE} |
|
uses SysUtils, Classes; |
|
var Srm1, |
//входной поток |
Srm2:TFileStream; |
//выходной поток |
SourceFileName, |
//имя входного файла |
DestFileName:string; //имя файла копии begin
//открываем файл источник данных write('Source file >> '); readln(SourceFileName);
try //в этом блоке может произойти ошибка try
//создаем поток в режиме только для чтения
Srm1:=TFileStream.Create(SourceFileName, fmOpenRead);
//создаем файл приемник write('Destination file >> '); readln(DestFileName);
//создаем поток в режиме создания нового потока
Srm2:=TFileStream.Create(DestFileName, fmCreate);
//копирование содержимого потока Srm1 в Srm2 Srm2.CopyFrom(Srm1, Srm1.Size); writeln('File success copy');
except
writeln('Fatal Error!'); end;
finally
//уничтожение объектов
Srm1.Free;
Srm2.Free;