Linux программирование в примерах
Работа осуществляется в цикле (строки 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 }4849 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 }5657 /* здесь все нормально */58 (void)close(fd);59 return 0;60 }Вот результаты запуска программы:
$ <b>ch04-holes peoplelist</b> /* Запустить программу */$ <b>ls -ls peoplelist</b> /* Показать использованные размеры и блоки */16 -rw-r--r-- 1 arnold devel 81944 Mar 23 17:43 peoplelist$ <b>echo 81944 / 4096 | bc -l</b> /* Показать блоки, если нет дыр */20.00585937500000000000Случайно мы знаем, что каждый дисковый блок файла использует 4096 байтов. (Откуда мы это знаем, обсуждается в разделе 5 4.2 «Получение информации о файле». Пока примите это как данное.) Финальная команда bc указывает, что файлу размером 81944 байтов нужен 21 дисковый блок. Однако, опция -s команды ls, которая сообщает нам, сколько блоков использует файл на самом деле, показывает, что файл использует лишь 16 блоков! [48] Отсутствующие блоки в файле являются дырами. Это показано на рис. 4.2.
Рис. 4.2. Дыры в файле
ЗАМЕЧАНИЕ.
не осуществляет непосредственный двоичный ввод/вывод. Это хорошо демонстрирует красоту ввода/вывода с произвольным доступом: вы можете рассматривать дисковый файл, как если бы он был очень большим массивом двоичных структур данных.ch04-holes.cНа практике сохранение данных путем использования двоичного ввода/вывода является решением, которое необходимо тщательно взвесить. Например, что если предположить, что вам нужно переместить данные на систему, использующую отличный порядок байтов для целых? Или другие форматы чисел с плавающей точкой? Или на систему с другими требованиями выравнивания? Игнорирование подобных вопросов может стать слишком дорогостоящим.
4.6. Создание файлов
Как было описано ранее,
, очевидно, открывает лишь существующие файлы. Данный раздел описывает, как создавать новые файлы. Есть две возможности:open()иcreat()с дополнительными файлами. Первоначальноopen()был единственным способом создания файла, но затем эта возможность была добавлена также и кcreat(). Оба механизма требуют указания начальных прав доступа к файлу.open()4.6.1. Определение начальных прав доступа к файлу
Как пользователь GNU/Linux, вы знакомы с правами доступа к файлу, выдаваемыми командой '
': на чтение, запись и исполнение для каждого из владельца файла, группы и остальных. Различные сочетания часто выражаются в восьмеричной форме, в частности, для командls -lиchmod. Например, права доступа к файлуchmaskr-- эквивалентны восьмеричному 0644, a-rw-r--эквивалентно восьмеричному 0755. (Ведущий 0 в нотации С означает восьмеричные значения.)-rwxr-xr-xКогда вы создаете файл, вы должны знать, какую защиту необходимо назначить новому файлу. Вы можете сделать это с помощью простого восьмеричного числа, если захотите, и такие числа довольно обычно можно увидеть в старом коде. Однако, лучше использовать побитовую операцию OR для одной или более символических имен из
, описанных в табл. 4.5.<sys/stat.h>Таблица 4.5. Символические имена POSIX для режимов доступа к файлу
Символическое имя Значение Комментарий S_IRWXU00700 Разрешение на чтение, запись и исполнение для владельца S_IRUSR00400 Разрешение на чтение для владельца S_IREADАналогично S_IRUSRS_IWUSR00200 Разрешение на запись для владельца S_IWRITEАналогично S_IWUSRS_IXUSR00100 Разрешение на исполнение для владельца. S_IEXECАналогично S_IXUSRS_IRWXG00070 Разрешение на чтение, запись и исполнение для группы S_IRGRP00040 Разрешение на чтение для группы S_IWGRP00020 Разрешение на запись для группы. S_IXGRP00010 Разрешение на исполнение для группы S_IRWXO00007 Разрешение на чтение, запись и исполнение для остальных. S_IROTH00004 Разрешение на чтение для остальных. S_IWOTH00002 Разрешение на запись для остальных S_IXOTH00001 Разрешение на исполнение для остальных
