Главная » Просмотр файлов » Керниган и Ритчи - Язык программирования Си

Керниган и Ритчи - Язык программирования Си (793773), страница 41

Файл №793773 Керниган и Ритчи - Язык программирования Си (Керниган и Ритчи - Язык программирования Си) 41 страницаКерниган и Ритчи - Язык программирования Си (793773) страница 412019-04-24СтудИзба
Просмтор этого файла доступен только зарегистрированным пользователям. Но у нас супер быстрая регистрация: достаточно только электронной почты!

Текст из файла (страница 41)

Эффективнее обмениваться большимчислом байтов, поскольку при этом требуется меньше системных вызовов. Используя полученные сведения,мы можем написать простую программу, копирующую свой ввод на свой вывод и эквивалентную программекопирования файла, описанной в главе 1 . С помощью этой программы можно копировать откуда угодно икуда угодно, поскольку всегда существует возможность перенаправить ввод-вывод на любой файл илиустройство.#include "syscalls.h"main() /* копирование ввода на вывод */{char buf[BUFSIZ];int n;while ((n = read(0, but, BUFSIZ)) > 0)write(i, but, n);return 0;}Прототипы функций, обеспечивающие системные вызовы, мы собрали в файле syscalls.h, что позволяетнам включать его в программы этой главы. Однако имя данного файла не зафиксировано стандартом.Параметр BUFSIZ также определен в <syscalls.h>; в каждой конкретной системе он имеет своезначение.

Если размер файла не кратен BUFSIZ, то какая-то операция чтения вернет значение меньшее, чемBUFSIZ, а следующее обращение к read даст в качестве результата нуль.Полезно рассмотреть, как используются read и write при написании программ более высокого уровня —таких как getchar, putchar и т.д. Вот, к примеру, версия программы getchar, которая осуществляетнебуферизованный ввод, читая по одному символу из стандартного входного потока.#include "syscalls.h"/* getchar: небуферизованный ввод одного символа */int getchar(void){char с;return (read(0, &c, 1) == 1) ? (unsigned char) с : EOF;}Переменная c должна быть типа char, поскольку read требует указателя на char. Приведение c кunsigned char перед тем, как вернуть ее в качестве результата, исключает какие-либо проблемы,связанные с распространением знака.Вторая версия getchar осуществляет ввод большими кусками, но при каждом обращении выдает толькоодин символ.#include "syscalls.h"/* getchar: простая версия с буферизацией */int getchar(void){static char buf[BUFSIZ];static char *bufp = buf;static int n = 0;if (n == 0) { /* буфер пуст '*/n = read(0, buf, sizeof buf);bufp = buf;}return (--n >= 0) ? (unsigned char) *bufp++ : EOF;}Если приведенные здесь версии функции getchar компилируются с включением заголовочного файла<stdio.h> и в этом заголовочном файле getchar определена как макрос, то нужно задать строку #undefс именем getchar.8.3.

Системные вызовы open, creat, close, unlinkВ отличие от стандартных файлов ввода, вывода и ошибок, которые открыты по умолчанию, остальные файлынужно открывать явно. Для этого есть два системных вызова: open и сreat.Функция open почти совпадает с fopen, рассмотренной в главе 7. Разница между ними в том, что перваявозвращает не файловый указатель, а дескриптор файла типа int. При любой ошибке open возвращает -1.#include <fcntl.h>int fd;int open(char *name, int flags, int perms);fd = open(name, flags, perms);Как и в fopen, аргумент name — это строка, содержащая имя файла. Второй аргумент, flags, имеет тип intи специфицирует, каким образом должен быть открыт файл. Его основными значениями являются:O_RDONLY— открыть только на чтение;O_WRONLY— открыть только на запись;O_RDWR— открыть и на чтение, и на запись.В System V UNIX эти константы определены в <fcntl.h>, а в версиях Berkeley (BSD) — в <sys/file.h>.Чтобы открыть существующий файл на чтение, можно написатьfd = open(name, O_RDONLY, 0);Далее везде, где мы пользуемся функцией open, ее аргумент perms равен нулю.Попытка открыть несуществующий файл является ошибкой.

Создание нового файла или перезапись старогообеспечивается системным вызовом creat. Напримерint creat(char *name, int perms);fd = сreat(name, perms);Функция creat возвращает дескриптор файла, если файл создан, и -1, если по каким-либо причинам файлсоздать не удалось. Если файл уже существует, creat "обрежет" его до нулевой длины, что равносильновыбрасыванию предыдущего содержимого данного файла; создание уже существующего файла не являетсяошибкой.Если строится действительно новый файл, то creat его создаст с правами доступа, специфицированными варгументе реrms. В системе UNIX с каждым файлом ассоциированы девять битов, содержащие информациюо правах пользоваться этим файлом для чтения, записи и исполнения лицам трех категорий: собственникуфайла, определенной им группе лиц и всем остальным.

Таким образом, права доступа удобноспецифицировать с помощью трех восьмеричных цифр. Например, 0755 специфицирует чтение, запись иправо исполнения собственнику файла, а также чтение и право исполнения группе и всем остальным.Для иллюстрации приведем упрощенную версию программы ср системы UNIX, которая копирует один файл вдругой. В нашей версии копируется только один файл, не позволяется во втором аргументе указыватьдиректорий (каталог), и права доступа не копируются, а задаются константой.#include <stdio.h>#include <fcntl.h>#include "syscalls.h"#define PERMS 0666 /* RW для собственника, группы и остальных */void error(char *, ...);/* ср: копирование f1 в f2 */main(int argc, char *argv[]){int f1, f2, n;char buf[BUFSIZ];if (argc != 3)еrrоr("Обращение: ср откуда куда");if ((f1 = open(argv[1], 0_RDONLY, 0)) == -1)error ("ср: не могу открыть файл %s", argv[1]);if ((f2 = creat(argv[2], PERMS)) == -1)error ("ср: не могу создать файл %s, режим %03о",argv[2], PERMS);while ((n = read(f1, buf, BUFSIZ)) > 0)if (write(f2, buf, n) != n)error ("ср: ошибка при записи в файл %s", argv[2]);return 0;}Данная программа создает файл вывода с фиксированными правами доступа, определяемыми кодом 0666.С помощью системного вызова stat, который будет описан в параграфе 8.6, мы можем определить режимиспользования существующего файла и задать тот же режим для копии.Заметим, что функция error, вызываемая с различным числом аргументов, во многом похожа на printf.Реализация error иллюстрирует, как пользоваться другими программами семейства printf.

Библиотечнаяфункция vprintf аналогична printf, с той лишь оговоркой, что переменная часть списка аргументовзаменена в ней одним аргументом, который инициализируется макросом va_start. Подобным же образомсоотносятся функции vfprintf с fprintf и vsprintf с sprintf.#include <stdio.h>#include <stdarg.h>/* error: печатает сообщение об ошибке и умирает */void error(char *fmt, ...){va_list args;va_start(args, fmt);fprintf(stderr, "ошибка: ");vfprintf(stderr, fmt, args);fprintf(stderr, "\n");va_end(args);exit(1);}На количество одновременно открытых в программе файлов имеется ограничение (обычно их числоколеблется около 20). Поэтому любая программа, которая намеревается работать с большим количествомфайлов, должна быть готова повторно использовать их дескрипторы.

Функция close(int fd) разрываетсвязь между файловым дескриптором и открытым файлом и освобождает дескриптор для его применения сдругим файлом. Она аналогична библиотечной функции fclose с тем лишь различием, что никакой очисткибуфера не делает. Завершение программы с помощью exit или return в главной программе закрывает всеоткрытые файлы.Функция unlink(char *name) удаляет имя файла из файловой системы. Она соответствует функцииremove стандартной библиотеки.Упражнение 8.1. Перепишите программу cat из главы 7, используя функции read, write, open и close.Замените ими соответствующие функции стандартной библиотеки.

Поэкспериментируйте, чтобы сравнитьбыстродействие двух версий.8.4. Произвольный доступ (lseek)Ввод-вывод обычно бывает последовательным, т. е. каждая новая операция чтения-записи имеет дело спозицией файла, следующей за той, что была в предыдущей операции (чтения-записи). При желании, однако,файл можно читать или производить запись в него в произвольном порядке. Системный вызов lseekпредоставляет способ передвигаться по файлу, не читая и не записывая данные. Так, функцияlong lseek(int fd, long offset, int origin);в файле с дескриптором fd устанавливает текущую позицию, смещая ее на величину offset относительноместа, задаваемого значением origin. Значения параметра origin 0, 1 или 2 означают, что на величинуoffset отступают соответственно от начала, от текущей позиции или от конца файла.

Например, еслитребуется добавить что-либо в файл (когда в командном интерпретаторе shell системы UNIX вводперенаправлен оператором >> в файл или когда в fopen задан аргумент "а"), то прежде чем что-либозаписывать, необходимо найти конец файла с помощью вызова функцииlseek(fd, 0L, 2);Чтобы вернуться назад, в начало файла, надо выполнитьlseek(fd, 0L, 0);Следует обратить внимание на аргумент 0L: вместо 0L можно было бы написать (long) 0 или, еслифункция lseek должным образом объявлена, просто 0.Благодаря lseek с файлами можно работать так, как будто это большие массивы, правда, с замедленнымдоступом.

Например, следующая функция читает любое число байтов из любого места файла. Она возвращаетчисло прочитанных байтов или -1 в случае ошибки.#include "syscalls.h"/* get: читает n байт из позиции роз */int get(int fd, long pos, char *buf, int n){if (lseek(fd, pos, 0) >= 0) /* установка позиции */return read(fd, buf, n);elsereturn -1;}Возвращаемое функцией lseek значение имеет тип long и является новой позицией в файле или, в случаеошибки, равно -1. Функция fseek из стандартной библиотеки аналогична lseek; от последней онаотличается тем, что в случае ошибки возвращает некоторое ненулевое значение, а ее первый аргумент имееттип FILE*.8.5. Пример.

Характеристики

Тип файла
PDF-файл
Размер
2,25 Mb
Тип материала
Высшее учебное заведение

Список файлов книги

Свежие статьи
Популярно сейчас
Почему делать на заказ в разы дороже, чем купить готовую учебную работу на СтудИзбе? Наши учебные работы продаются каждый год, тогда как большинство заказов выполняются с нуля. Найдите подходящий учебный материал на СтудИзбе!
Ответы на популярные вопросы
Да! Наши авторы собирают и выкладывают те работы, которые сдаются в Вашем учебном заведении ежегодно и уже проверены преподавателями.
Да! У нас любой человек может выложить любую учебную работу и зарабатывать на её продажах! Но каждый учебный материал публикуется только после тщательной проверки администрацией.
Вернём деньги! А если быть более точными, то автору даётся немного времени на исправление, а если не исправит или выйдет время, то вернём деньги в полном объёме!
Да! На равне с готовыми студенческими работами у нас продаются услуги. Цены на услуги видны сразу, то есть Вам нужно только указать параметры и сразу можно оплачивать.
Отзывы студентов
Ставлю 10/10
Все нравится, очень удобный сайт, помогает в учебе. Кроме этого, можно заработать самому, выставляя готовые учебные материалы на продажу здесь. Рейтинги и отзывы на преподавателей очень помогают сориентироваться в начале нового семестра. Спасибо за такую функцию. Ставлю максимальную оценку.
Лучшая платформа для успешной сдачи сессии
Познакомился со СтудИзбой благодаря своему другу, очень нравится интерфейс, количество доступных файлов, цена, в общем, все прекрасно. Даже сам продаю какие-то свои работы.
Студизба ван лав ❤
Очень офигенный сайт для студентов. Много полезных учебных материалов. Пользуюсь студизбой с октября 2021 года. Серьёзных нареканий нет. Хотелось бы, что бы ввели подписочную модель и сделали материалы дешевле 300 рублей в рамках подписки бесплатными.
Отличный сайт
Лично меня всё устраивает - и покупка, и продажа; и цены, и возможность предпросмотра куска файла, и обилие бесплатных файлов (в подборках по авторам, читай, ВУЗам и факультетам). Есть определённые баги, но всё решаемо, да и администраторы реагируют в течение суток.
Маленький отзыв о большом помощнике!
Студизба спасает в те моменты, когда сроки горят, а работ накопилось достаточно. Довольно удобный сайт с простой навигацией и огромным количеством материалов.
Студ. Изба как крупнейший сборник работ для студентов
Тут дофига бывает всего полезного. Печально, что бывают предметы по которым даже одного бесплатного решения нет, но это скорее вопрос к студентам. В остальном всё здорово.
Спасательный островок
Если уже не успеваешь разобраться или застрял на каком-то задание поможет тебе быстро и недорого решить твою проблему.
Всё и так отлично
Всё очень удобно. Особенно круто, что есть система бонусов и можно выводить остатки денег. Очень много качественных бесплатных файлов.
Отзыв о системе "Студизба"
Отличная платформа для распространения работ, востребованных студентами. Хорошо налаженная и качественная работа сайта, огромная база заданий и аудитория.
Отличный помощник
Отличный сайт с кучей полезных файлов, позволяющий найти много методичек / учебников / отзывов о вузах и преподователях.
Отлично помогает студентам в любой момент для решения трудных и незамедлительных задач
Хотелось бы больше конкретной информации о преподавателях. А так в принципе хороший сайт, всегда им пользуюсь и ни разу не было желания прекратить. Хороший сайт для помощи студентам, удобный и приятный интерфейс. Из недостатков можно выделить только отсутствия небольшого количества файлов.
Спасибо за шикарный сайт
Великолепный сайт на котором студент за не большие деньги может найти помощь с дз, проектами курсовыми, лабораторными, а также узнать отзывы на преподавателей и бесплатно скачать пособия.
Популярные преподаватели
Добавляйте материалы
и зарабатывайте!
Продажи идут автоматически
7026
Авторов
на СтудИзбе
260
Средний доход
с одного платного файла
Обучение Подробнее