Скачиваний:
56
Добавлен:
08.01.2014
Размер:
2.6 Mб
Скачать

2.2.3. Использование стандартного вывода диагностики

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

$ make > log.out 2>log.err

В результате все сообщения об ошибках работы make направляются в файл log.err, а стандартный вывод направляется в файл log.out.

Можно выводить сообщения в стандартный вывод диагностики при помощи системного вызова write со значением дескриптора файла равным 2:

var

msg:array [0..5] of char='boob'#$a;

.

.

fdwrite(2, msg, 5);

Тем не менее это достаточно грубый и громоздкий способ. Мы приведем лучшее решение в конце этой главы.

2.3. Стандартная библиотека ввода/вывода: взгляд в будущее

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

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

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

uses stdio;

var

stream:PFILE;

begin

stream := fopen ('junk', 'r');

if stream = nil then

begin

printf('Невозможно открыть файл junk'#10,[]);

halt(1);

end;

end.

Первая строка примера

uses stdio;

подключает модуль библиотеки ввода/вывода stdio, описанной в приложении. Этот файл, кроме всего прочего, содержит определение TFILE, PFILE и объявления для таких функций, как fopen.

Настоящее содержание этого примера заключается в операторе:

stream := fopen ('junk', 'r');

if stream = nil then

begin

.

.

end;

Здесь junk – это имя файла, а строка 'r' означает, что файл открывается только для чтения. Строка 'w' может использоваться для усечения файла до нулевой длины или создания файла и открытия его на запись. В случае успеха функция fopen проинициализирует структуру TFILE и вернет ее адрес в переменной stream. Указатель stream может быть передан другим процедурам из библиотеки. Важно понимать, что где-то внутри тела функции fopen осуществляется вызов нашего старого знакомого fdopen. И, естественно, где-то внутри структуры TFILE находится дескриптор файла, привязывающий структуру к файлу. Существенно то, что процедуры стандартного ввода/вывода написаны на основе примитивов системных вызовов. Основная функция библиотеки состоит в создании более удобного интерфейса и автоматической буферизации.

После открытия файла существует множество стандартных процедур ввода/ вывода для доступа к нему. Одна из них – процедура getc, считывающая одиночный символ, другая, putc, выводит один символ. Они используются следующим образом:

Соседние файлы в папке Полищук, Семериков. Системное программирование в UNIX средствами Free Pascal