Кроме случая, когда по умолчанию определены стандартныефайлы ввода, вывода и ошибок, вы должны явно открывать фай-лы, чтобы затем читать из них или писать в них. Для этой це-ли существуют две точки входа: OPEN и CREAT. Функция OPEN весьма сходна с функцией FOPEN, рассмотрен-ной в главе 7, за исключением того, что вместо возвращенияуказателя файла она возвращает дескриптор файла, который яв-ляется просто целым типа INT. INT FD;FD=OPEN(NAME,RWMODE); Как и в случае FOPEN, аргумент NAME является символьнойстрокой, соответствующей внешнему имени файла. Однако аргу-мент, определяющий режим доступа, отличен: RWMODE равно: 0 -для чтения, 1 - для записи, 2 - для чтения и записи. Еслипроисходит какая-то ошибка, функция OPEN возвращает "-1"; впротивном случае она возвращает действительный дескрипторфайла. Попытка открыть файл, который не существует, являетсяошибкой. Точка входа CREAT предоставляет возможность созда-ния новых файлов или перезаписи старых. В результате обраще-ния FD=CREAT(NAME,PMODE); возвращает дескриптор файла, если оказалось возможным соз-дать файл с именем NAME, и "-1" в противном случае. Еслифайл с таким именем уже существует, CREAT усечет его до ну-левой длины; создание файла, который уже существует, не яв-ляется ошибкой. Если файл является совершенно новым, то CREAT создаетего с определенным режимом защиты, специфицируемым аргумен-том PMODE. В системе файлов на UNIX с файлом связываются де-вять битов защиты информации, которые управляют разрешениемна чтение, запись и выполнение для владельца файла, длягруппы владельцев и для всех остальных пользователей. Такимобразом, трехзначное восьмеричное число наиболее удобно дляспецификации разрешений. Например, число 0755 свидетельству-ет о разрешении на чтение, запись и выполнение для владельцаи о разрешении на чтение и выполнение для группы и всех ос-тальных. Для иллюстрации ниже приводится программа копированияодного файла в другой, являющаяся упрощенным вариантом ути-литы CP системы UNIX. (Основное упрощение заключается в том,что наш вариант копирует только один файл и что второй аргу-мент не должен быть справочником). #DEFINE NULL 0 #DEFINE BUFSIZE 512 #DEFINE PMODE 0644/*RW FOR OWNER,R FOR GROUP,OTHERS*/ MAIN(ARGC,ARGV) /*CP: COPY F1 TO F2*/ INT ARGC; CHAR *ARGV[]; \( INT F1, F2, N; CHAR BUF[BUFSIZE]; IF (ARGC ! = 3) ERROR("USAGE:CP FROM TO", NULL); IF ((F1=OPEN(ARGV[1],0))== -1) ERROR("CP:CAN'T OPEN %S", ARGV[1]); IF ((F2=CREAT(ARGV[2],PMODE))== -1) ERROR("CP: CAN'T CREATE %S", ARGV[2]); WHILE ((N=READ(F1,BUF,BUFSIZE))>0) IF (WRITE(F2,BUF,N) !=N) ERROR("CP: WRITE ERROR", NULL); EXIT(0); \) ERROR(S1,S2) /*PRINT ERROR MESSAGE AND DIE*/ CHAR *S1, S2; \( PRINTF(S1,S2); PRINTF("\N"); EXIT(1); \) Существует ограничение (обычно 15 - 25) на количествофайлов, которые программа может иметь открытыми одновремен-но. В соответствии с этим любая программа, собирающаяся ра-ботать со многими файлами, должна быть подготовлена к пов-торному использованию дескрипторов файлов. Процедура CLOSEпрерывает связь между дескриптором файла и открытым файлом иосвобождает дескриптор файла для использования с некоторымдругим файлом. Завершение выполнения программы через EXITили в результате возврата из ведущей программы приводит кзакрытию всех открытых файлов. Функция расцепления UNLINK (FILENAME) удаляет из системыфайлов файл с именем FILENAME ( из данного справочного фай-ла. Файл может быть сцеплен с другим справочником, возможно,под другим именем - примеч.переводчика). Упражнение 8-1 -------------- Перепишите программу CAT из главы 7, используя функцииREAD, WRITE, OPEN и CLOSE вместо их эквивалентов из стандар-тной библиотеки. Проведите эксперименты для определения от-носительной скорости работы этих двух вариантов.