Чтение онлайн

на главную - закладки

Жанры

Разработка приложений в среде Linux. Второе издание

Троан Эрик В.

Шрифт:

Параметр

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
в случае ошибки (это означает, что ничего не было прочитано или записано).

42

readv
,
writev
и
mmap
обсуждаются в главе 13;
sendmsg
и
recvmsg
упоминаются в главе 17.

Теперь, когда мы описали эти системные вызовы, рассмотрим простой пример, создающий файл

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, "Добро пожаловать!\n", 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

cat: hw: Файл или каталог не существует

$ ./hwwrite

$ cat hw

Добро пожаловать!

$

Для изменения этой программы, чтобы она читала файл, нужно просто изменить

open
, как показано ниже, и заменить
write
статической строки на
read
в буфер.

open("hw", O_RDONLY);

Файлы Unix можно разделить на две категории: просматриваемые (seekable) и непросматриваемые (nonseekable) [43] . Непросматриваемые файлы представляют собой каналы, работающие в режиме "первый вошел — первый вышел" (FIFO), которые не поддерживают произвольное чтение или запись, их данные не могут быть перечитаны или перезаписаны. Просматриваемые файлы позволяют читать и писать в произвольное

место файла. Каналы и сокеты являются не просматриваемыми файлами; блоковые устройства и обычные файлы являются просматриваемыми.

43

Хотя такое разделение почти ясно, сокеты TCP поддерживают "внеполосные" данные, что несколько усложняет ситуацию. Такие данные выходят за пределы тем, рассматриваемых в этой книге. Их полное описание можно найти в [33].

Поскольку FIFO — это непросматриваемые файлы, то, очевидно, что

read
читает их с начала, a
write
пишет в конец. С другой стороны, просматриваемые файлы не имеют очевидной точки для этих операций. Вместо этого здесь вводится понятие "текущего" положения, которое перемещается вперед после операции. Когда просматриваемый файл изначально открывается, текущее положение устанавливается в его начало, со смещением 0. Если затем из него читается 10 байт, то текущее положение перемещается в точку со смещением 10 от начала, а запись 5 байт переписывает данные, начиная с одиннадцатого байта в файле (то есть, со смещения 10, где расположена текущая позиция после чтения). После такой записи текущая позиция находится в позиции, смещенной на 15 относительно начала файла — сразу после перезаписанных данных.

Если текущая позиция совпадает с концом файла и процесс пытается читать их этого файла, то

read
возвращает 0 вместо ошибки. Если же данные записываются в конец файла, то он растет с тем, чтобы вместить дополнительные данные, и его текущая позиция устанавливается в конец файла. Каждый файловый дескриптор отслеживает независимую текущую позицию [44] (она не хранится в файловом inode), поэтому если файл открыт множество раз множеством процессов, или несколько раз одним и тем же процессом, то чтения и записи, выполняемые через один дескриптор, никак не влияют на позиции чтения и записи, выполненные через другой дескриптор. Конечно, множественные операции записи могут повредить файл другими способами, поэтому блокировка определенного рода в такой ситуации может понадобиться.

44

Почти независимую; см. описание исключений из этого правила в дискуссии о

dup
в конце этой главы.

Файлы, открытые с флагом

O_APPEND
ведут себя несколько иначе. Для таких файлов текущая позиция перемещается в конец файла перед тем, как ядро осуществит в него запись. После записи текущая позиция перемещается в конец записанных данных, как обычно. Для файлов, работающих в режиме только для добавления, это гарантирует, что текущая позиция файла всегда будет находиться в его конце немедленно после вызова
write
.

Приложения, которые хотят читать и писать данные с произвольного места файла, должны установить текущую позицию перед выполнением операции чтения или записи данных, используя

lseek
.

#include <unistd.h>

int lseek(int fd, off_t offset, int whence);

Текущая позиция для файла

fd
перемещается на
offset
байт относительно
whence
, где whence принимает одно из следующих значений:

SEEK_SET
[45] Начало файла.

SEEK_CUR
Текущая позиция в файле.

SEEK_END
Конец файла.

Для

SEEK_CUR
и
SEEK_END
значение
offset
может быть отрицательным. В этом случае текущая позиция перемещается в сторону начала файла (от
whence
), а не в сторону конца. Например, приведенный ниже код перемещает текущую позицию на 5 байт назад от конца файла.

45

Поскольку в большинстве систем

SEEK_SET
определена как 0, часто можно увидеть использование
lseek(fd, offset, 0)
вместо
lseek(fd, offset, SEEK_SET)
. Это делает код непереносимым (или плохо читабельным), чем
SEEK_SET
, но подобное часто встречается в старом коде.

Поделиться:
Популярные книги

Черный Маг Императора 6

Герда Александр
6. Черный маг императора
Фантастика:
юмористическое фэнтези
попаданцы
аниме
7.00
рейтинг книги
Черный Маг Императора 6

Оцифрованный. Том 1

Дорничев Дмитрий
1. Линкор Михаил
Фантастика:
боевая фантастика
попаданцы
аниме
5.00
рейтинг книги
Оцифрованный. Том 1

Кодекс Охотника. Книга XIV

Винокуров Юрий
14. Кодекс Охотника
Фантастика:
боевая фантастика
попаданцы
аниме
5.00
рейтинг книги
Кодекс Охотника. Книга XIV

Штуцер и тесак

Дроздов Анатолий Федорович
1. Штуцер и тесак
Фантастика:
боевая фантастика
альтернативная история
8.78
рейтинг книги
Штуцер и тесак

Я снова граф. Книга XI

Дрейк Сириус
11. Дорогой барон!
Фантастика:
боевая фантастика
попаданцы
аниме
5.00
рейтинг книги
Я снова граф. Книга XI

Болотник

Панченко Андрей Алексеевич
1. Болотник
Фантастика:
попаданцы
альтернативная история
6.50
рейтинг книги
Болотник

Кодекс Крови. Книга III

Борзых М.
3. РОС: Кодекс Крови
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Кодекс Крови. Книга III

Жестокая свадьба

Тоцка Тала
Любовные романы:
современные любовные романы
4.87
рейтинг книги
Жестокая свадьба

Стеллар. Трибут

Прокофьев Роман Юрьевич
2. Стеллар
Фантастика:
боевая фантастика
рпг
8.75
рейтинг книги
Стеллар. Трибут

Голодные игры

Коллинз Сьюзен
1. Голодные игры
Фантастика:
социально-философская фантастика
боевая фантастика
9.48
рейтинг книги
Голодные игры

Последняя Арена 8

Греков Сергей
8. Последняя Арена
Фантастика:
боевая фантастика
рпг
5.00
рейтинг книги
Последняя Арена 8

Черный маг императора 2

Герда Александр
2. Черный маг императора
Фантастика:
юмористическая фантастика
попаданцы
аниме
6.00
рейтинг книги
Черный маг императора 2

Последний Паладин

Саваровский Роман
1. Путь Паладина
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Последний Паладин

Измена. Свадьба дракона

Белова Екатерина
Любовные романы:
любовно-фантастические романы
эро литература
5.00
рейтинг книги
Измена. Свадьба дракона