Хрестоматия по программированию на Си в Unix


Работа с файлами. Хрестоматия по программированию на Си в Unix - стр. 2


Способ 1: register i; for(i=0; i<3; i++){ putchar( '\7' ); fflush(stdout); sleep(1); /* пауза 1 сек. */ }

Способ 2: register i; for(i=0; i<3; i++){ write(1, "\7", 1 ); sleep(1); }

Почему задержка не ощущается?

printf( "Пауза..."); sleep ( 5 ); /* ждем 5 сек. */ printf( "продолжаем\n" );

Ответ: из-за буферизации канала stdout. Первая фраза попадает в буфер и, если он не заполнился, не выдается на экран. Дальше программа "молчаливо" ждет 5 секунд. Обе фразы будут выданы уже после задержки! Чтобы первый printf() выдал свою фразу ДО задержки, следует перед функцией sleep() вставить вызов fflush(stdout) для явного выталкивания буфера. Замечание: канал stderr не буферизован, поэтому проблему можно решить и так:

fprintf( stderr, "Пауза..." );

Еще один пример про буферизацию. Почему программа печатает EOF?

#include <stdio.h>

FILE *fwr, *frd; char b[40], *s; int n = 1917; main(){ fwr = fopen( "aFile", "w" ); frd = fopen( "aFile", "r" ); fprintf( fwr, "%d: Hello, dude!", n); s = fgets( b, sizeof b, frd ); printf( "%s\n", s ? s : "EOF" ); }

Ответ: потому что к моменту чтения буфер канала fwr еще не вытолкнут в файл: файл пуст! Надо вставить

fflush(fwr);

после fprintf(). Вот еще подобный случай:

FILE *fp = fopen("users", "w"); ... fprintf(fp, ...); ... system("sort users | uniq > 00; mv 00 users");

К моменту вызова команды сортировки буфер канала fp (точнее, последний из накопленных за время работы буферов) может быть еще не вытолкнут в файл. Следует либо закрыть файл fclose(fp) непосредственно перед вызовом system, либо вставить туда же fflush(fp);

В UNIX многие внешние устройства (практически все!) с точки зрения программ являются просто файлами. Файлы-устройства имеют имена, но не занимают места на диске (не имеют блоков). Зато им соответствуют специальные программы-драйверы в ядре. При открытии такого файла-устройства мы на самом деле инициализируем драйвер этого устройства, и в дальнейшем он выполняет наши запросы read, write, lseek аппаратнозависимым образом. Для операций, специфичных для данного устройства, предусмотрен сисвызов ioctl (input/output control):




- Начало -  - Назад -  - Вперед -