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

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

Жанры

Linux программирование в примерах

Роббинс Арнольд

Шрифт:

Большое количество старого кода использует числовые значения, приведенные в табл. 4.4. Однако, любой новый код, который вы пишете, должен использовать символические имена, значение которых более ясно.

Смысл значений и их действие на положение в файле показаны на рис. 4.1. При условии, что файл содержит 3000 байтов и что перед каждым вызовом

lseek
текущим является смещение 2000 байтов, новое положение после каждого вызова будет следующим.

Рис. 4.1. Смещения для

lseek

Отрицательные смещения относительно начала файла бессмысленны; они вызывают ошибку «недействительный параметр».

Возвращаемое значение является новым положением в файле. Поэтому, чтобы получить ваше текущее местоположение в файле, используйте

off_t curpos;

...

curpos = lseek(fd, (off_t)0, SEEK_CUR);

Буква

l
в
lseek
означает
long
.
lseek
был введен в V7 Unix, когда размеры файлов были увеличены; в V6 был простой системный вызов
seek
. В результате большое количество старой документации (и кода) рассматривает параметр offset как имеющий тип
long
, и вместо приведения к типу
off_t
довольно часто можно видеть суффикс L в константных значениях смешений:

curpos = lseek(fd, 0L, SEEK_CUR);

На системах с компилятором стандартного С, где

lseek
объявлена с прототипом, такой старый код продолжает работать, поскольку компилятор автоматически преобразует 0L из
long
в
off_t
, если это различные типы.

Одной интересной и важной особенностью

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

Следующая программа демонстрирует создание дыр. Она записывает три экземпляра

struct
в начало, середину и дальний конец файла. Выбранные смешения (строки 16–18, третий элемент каждой структуры) произвольны, но достаточно большие для демонстрации особенности:

1 /* ch04-holes.c --- Демонстрация lseek и дыр в файлах. */

2

3 #include <stdio.h> /* для fprintf, stderr, BUFSIZ */

4 #include <errno.h> /* объявление errno */

5 #include <fcntl.h> /* для flags для open */

6 #include <string.h> /* объявление strerror */

7 #include <unistd.h> /* для ssize_t */

8 #include <sys/types.h> /* для off_t, etc. */

9 #include <sys/stat.h> /* для mode_t */

10

11 struct person {

12 char name[10]; /* имя */

13 char id[10]; /* идентификатор */

14 off_t pos; /* положение в файле для демонстрации */

15 } people[] = {

16 { "arnold", "123456789", 0 },

17 { "miriam", "987654321", 10240 },

18 { "joe", "192837465", 81920 },

19 };

20

21 int

22 main(int argc, char **argv)

23 {

24 int fd;

25 int i, j;

26

27 if (argc < 2) {

28 fprintf(stderr, "usage: %s file\n", argv[0]);

29 return 1;

30 }

31

32 fd = open(argv[1], O_RDWR | O_CREAT | O_TRUNC, 0666);

33 if (fd < 0) {

34 fprintf(stderr, "%s: %s: cannot open for read/write: %s\n",

35 argv[0], argv[1], strerror(errno));

36 return 1;

37 }

38

39 j = sizeof(people) / sizeof(people[0]); /* число элементов */

Строки 27–30 гарантируют, что программа была вызвана правильно. Строки 32–37 открывают именованный файл и проверяют успешность открытия.

Вычисление числа элементов

j
массива в строке 39 использует отличный переносимый трюк число элементов является размером всего массива, поделенного на размер первого элемента. Красота этого способа в том, что он всегда верен: неважно, сколько элементов вы добавляете в массив или удаляете из него, компилятор это выяснит. Он не требует также завершающей сигнальной метки; т.е. элемента, в котором все поля содержат нули,
NULL
или т.п.

Работа осуществляется в цикле (строки 41–55), который отыскивает смещение байтов, приведенное в каждой структуре (строка 42), а затем записывает всю структуру (строка 49):

41 for (i = 0; i < j; i++) {

42 if (lseek(fd, people[i].pos, SEEK_SET) < 0) {

43 fprintf(stderr, "%s: %s: seek error: %s\n",

44 argv[0], argv[1], strerror(errno));

45 (void)close(fd);

46 return 1;

47 }

48

49 if (write(fd, &people[i], sizeof(people[i])) != sizeof(people[i])) {

50 fprintf(stderr, "%s: %s: write error: %s\n",

51 argv[0], argv[1], strerror(errno));

52 (void)close(fd);

53 return 1;

54 }

55 }

56

57 /* здесь все нормально */

58 (void)close(fd);

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

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

Герда Александр
3. Черный маг императора
Фантастика:
попаданцы
аниме
5.00
рейтинг книги
Черный маг императора 3

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

Винокуров Юрий
4. Кодекс Охотника
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Кодекс Охотника. Книга IV

Тринадцатый

NikL
1. Видящий смерть
Фантастика:
фэнтези
попаданцы
аниме
6.80
рейтинг книги
Тринадцатый

Жена по ошибке

Ардова Алиса
Любовные романы:
любовно-фантастические романы
7.71
рейтинг книги
Жена по ошибке

Курсант: назад в СССР

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

Древесный маг Орловского княжества

Павлов Игорь Васильевич
1. Орловское княжество
Фантастика:
аниме
фэнтези
фантастика: прочее
попаданцы
5.00
рейтинг книги
Древесный маг Орловского княжества

Властелин Севера

Корнуэлл Бернард
3. Саксонские хроники
Приключения:
исторические приключения
8.67
рейтинг книги
Властелин Севера

Московское золото или нежная попа комсомолки. Часть Вторая

Хренов Алексей
2. Летчик Леха
Фантастика:
попаданцы
5.00
рейтинг книги
Московское золото или нежная попа комсомолки. Часть Вторая

Третий. Том 2

INDIGO
2. Отпуск
Фантастика:
космическая фантастика
попаданцы
5.00
рейтинг книги
Третий. Том 2

И в аду есть герои

Панов Вадим Юрьевич
5. Тайный Город
Фантастика:
боевая фантастика
9.19
рейтинг книги
И в аду есть герои

Вернувшийся: Первые шаги. Том II

Vector
2. Вернувшийся
Фантастика:
боевая фантастика
космическая фантастика
рпг
5.00
рейтинг книги
Вернувшийся: Первые шаги. Том II

Воплощение Похоти

Некрасов Игорь
1. Воплощение Похоти
Фантастика:
юмористическое фэнтези
попаданцы
рпг
аниме
5.00
рейтинг книги
Воплощение Похоти

#Бояръ-Аниме. Газлайтер. Том 24

Володин Григорий Григорьевич
24. История Телепата
Фантастика:
боевая фантастика
попаданцы
аниме
5.00
рейтинг книги
#Бояръ-Аниме. Газлайтер. Том 24

Хозяин Теней

Петров Максим Николаевич
1. Безбожник
Фантастика:
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Хозяин Теней