(см. главу 10). Этот флаг имеет значение только тогда, когда процесс, не имеющий управляющего терминала, открывает устройство tty. Если же он указан в любом другом случае, этот флаг игнорируется. | |
O_TRUNC | Если файл уже существует, его содержимое отбрасывается, и его размер устанавливается равным 0. |
O_APPEND | Все операции записи выполняются в конец файла, хотя произвольный доступ по чтению также разрешен. |
O_NONBLOCK | Файл открывается в неблокирующем режиме. Операции с нормальными файлами всегда блокируются, потому что они работают с локальными жесткими дисками, имеющими предсказуемое время отклика, но операции на некоторых типах файлов требуют непредсказуемого времени для завершения. Например, чтение из канала, в котором нет данных, блокирует процесс чтения до тех пор, пока данные в нем не появятся. Если же специфицирован флаг O_NONBLOCK , вызов read() вместо блокирования вернет ноль байт. Файлы, на операции с которыми может понадобиться непредсказуемый объем времени, называются медленными файлами. (O_NDELAY — оригинальное имя O_NONBLOCK , теперь устаревшее.) |
O_SYNC | Обычно ядро перехватывает операции записи и сбрасывает их на физическое устройство тогда, когда это удобно. Хотя такая реализация значительно повышает производительность, появляется также возможность потери данных, чем в том случае, когда они немедленно пишутся на диск. Если при открытии файла указан флаг O_SYNC , то все изменения в файле сохраняются на диске перед тем, как ядро возвращает управления процессу, выполняющему запись. Это очень важно для некоторых приложений, таких как системы управления базами данных, в которых принудительная запись используется для предотвращения повреждения данных в случае сбоя системы. |
Параметр mode
указывает права доступа для файла, если он создается и если он модифицируется текущей установкой umask
процесса. Если не указано O_CREAT
, то mode
игнорируется.
Функция creat()
в точности эквивалентна следующему вызову:
open(pathname, O_CREAT | O_WRONLY | O_TRUNC, mode)
Мы не используем creat()
в этой книге, потому что находим функцию open ()
более простой для чтения и понимания.
11.2.4. Чтение, запись и перемещение
Хотя есть несколько способов читать и писать файлы, мы обсудим здесь только простейшие из них[42]. Чтение и запись почти идентичны, поэтому рассмотрим их одновременно.
#include <unistd.h>
size_t read(int fd, void * buf, size_t length);
size_t read(int fd, const void * buf, size_t length);
Обе функции принимают файловый дескриптор fd
, указатель на буфер buf
и длину буфера length
, read()
читает из файлового дескриптора и помещает полученные данные в буфер; write()
пишет length
байт из буфера в файл. Обе функции возвращают количество переданных байт, или -1
в случае ошибки (это означает, что ничего не было прочитано или записано).
Теперь, когда мы описали эти системные вызовы, рассмотрим простой пример, создающий файл hw
в текущем каталоге и записывающий в него строку 'Добро пожаловать!'.
1: /* hwwrite.с */
2:
3: #include <errno.h>
4: #include <fcntl.h>
5: #include <stdio.h>
6: #include <stdlib.h>
7: #include <unistd.h>
8:
9: int main(void) {
10: int fd;
11:
12: /* открыть файл, создавая его, если он не существовал, и удаляя
13: его содержимое в противном случае */
14: if ((fd = open('hw', O_TRUNC | O_CREAT | O_WRONLY, 0644)) < 0) {
15: perror('open');
16: exit(1);
17: }
18:
19: /* магическое число 18 - это кол-во символов, которые
20: будут записаны */
21: if (write(fd, 'Добро пожаловать!
', 18) != 18) {
22: perror('write');
23: exit(1);
24: }
25:
26: close(fd);
27:
28: return 0;
29: }
Ниже показано, что получится, если запустить hwwrite
.
$ cat hw
cat: hw: No such file or directory
$ ./hwwrite
$ cat hw
Добро пожаловать!