Читаем Linux API. Исчерпывающее руководство полностью

Наличие дыр означает, что номинальный размер файла может быть больше, чем занимаемый им объем дискового пространства (иногда существенно больше). Запись байтов в середину дыры сократит объем свободного дискового пространства, поскольку для заполнения дыры ядро выделит блоки, даже притом, что размер файла не изменится. Подобное случается редко, но это все равно следует иметь в виду.

В SUSv3 определена функция posix_fallocate(fd, offset, len). Она гарантирует выделение дискового пространства для байтового диапазона, указанного аргументами offset и len для дискового файла, ссылка на который дается в дескрипторе fd. Это позволяет приложению получить гарантию, что при последующем вызове write() в отношении данного файла не будет сбоя, связанного с исчерпанием дискового пространства (который в противном случае может произойти при заполнении дыры в файле или потреблении дискового пространства каким-нибудь другим приложением). Исторически, реализация этой функции в glibc достигает нужного результата, записывая в каждый блок указанного диапазона нули. Начиная с версии 2.6.23, в Linux предоставляется системный вызов fallocate(). Он предлагает более эффективный способ обеспечения выделения необходимого пространства, и реализация posix_fallocate() в glibc использует этот системный вызов при его доступности.

В разделе 14.4 описывается способ представления дыр в файле, а в разделе 15.1 рассматривается системный вызов stat(), который способен сообщить о текущем размере файла, а также о количестве блоков, фактически выделенных файлу.

Пример программы

В листинге 4.3 показывается использование вызова lseek() в сочетании с read() и write(). Первый аргумент, передаваемый в командной строке для запуска этой программы, является именем открываемого файла. В остальных аргументах указываются операции ввода-вывода, выполняемые в отношении файла. Название каждой из этих операций состоит из буквы, за которой следует связанное с ней значение (без разделительного пробела):

• soffset — установка байтового смещения offset с начала файла;

• rlength — чтение length байтов из файла, начиная с текущего файлового смещения, и вывод их в текстовой форме;

• Rlength — чтение length байтов из файла, начиная с текущего файлового смещения и вывод их в виде шестнадцатеричных чисел;

• wstr — запись строки символов, указанной в str, начиная с позиции текущего файлового смещения.

Листинг 4.3. Демонстрация работы read(), write() и lseek()

fileio/seek_io.c

#include

#include

#include

#include "tlpi_hdr.h"

int

main(int argc, char *argv[])

{

size_t len;

off_t offset;

int fd, ap, j;

char *buf;

ssize_t numRead, numWritten;

if (argc < 3 || strcmp(argv[1], "-help") == 0)

usageErr("%s file {r|R|w|s}…\n",

argv[0]);

fd = open(argv[1], O_RDWR | O_CREAT,

S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP |

S_IROTH | S_IWOTH); /* rw-rw-rw- */

if (fd == -1)

errExit("open");

for (ap = 2; ap < argc; ap++) {

switch (argv[ap][0]) {

case 'r': /* Вывод байтов с позиции текущего смещения в виде текста */

case 'R': /* Вывод байтов с позиции текущего смещения в виде hex-чисел */

len = getLong(&argv[ap][1], GN_ANY_BASE, argv[ap]);

buf = malloc(len);

if (buf == NULL)

errExit("malloc");

numRead = read(fd, buf, len);

if (numRead == -1)

errExit("read");

if (numRead == 0) {

printf("%s: end-of-file\n", argv[ap]);

} else {

printf("%s: ", argv[ap]);

for (j = 0; j < numRead; j++) {

if (argv[ap][0] == 'r')

printf("%c", isprint((unsigned char) buf[j])?

buf[j]: '?');

else

printf("%02x", (unsigned int) buf[j]);

}

printf("\n");

}

free(buf);

break;

case 'w': /* Запись строки, начиная с позиции текущего смещения */

numWritten = write(fd, &argv[ap][1], strlen(&argv[ap][1]));

if (numWritten == -1)

errExit("write");

printf("%s: wrote %ld bytes\n", argv[ap], (long) numWritten);

break;

case 's': /* Изменение файлового смещения */

offset = getLong(&argv[ap][1], GN_ANY_BASE, argv[ap]);

if (lseek(fd, offset, SEEK_SET) == -1)

errExit("lseek");

printf("%s: seek succeeded\n", argv[ap]);

break;

default:

cmdLineErr("Argument must start with [rRws]: %s\n", argv[ap]);

}

}

exit(EXIT_SUCCESS);

}

fileio/seek_io.c

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

$ touch tfile Создание нового, пустого файла5

$ ./seek_io tfile s100000 wabc Установка смещения 100000, запись “abc”

s100000: seek succeeded

wabc: wrote 3 bytes

$ ls — l tfile Проверка размера файла

— rw-r-r- 1 mtk users 100003 Feb 10 10:35 tfile

$ ./seek_io tfile s10000 R5 Установка смещения 10000, чтение пяти байт из дыры

s10000: seek succeeded

R5: 00 00 00 00 00 В байтах дыры содержится 0

Перейти на страницу:

Похожие книги

1С: Бухгалтерия 8 с нуля
1С: Бухгалтерия 8 с нуля

Книга содержит полное описание приемов и методов работы с программой 1С:Бухгалтерия 8. Рассматривается автоматизация всех основных участков бухгалтерии: учет наличных и безналичных денежных средств, основных средств и НМА, прихода и расхода товарно-материальных ценностей, зарплаты, производства. Описано, как вводить исходные данные, заполнять справочники и каталоги, работать с первичными документами, проводить их по учету, формировать разнообразные отчеты, выводить данные на печать, настраивать программу и использовать ее сервисные функции. Каждый урок содержит подробное описание рассматриваемой темы с детальным разбором и иллюстрированием всех этапов.Для широкого круга пользователей.

Алексей Анатольевич Гладкий

Программирование, программы, базы данных / Программное обеспечение / Бухучет и аудит / Финансы и бизнес / Книги по IT / Словари и Энциклопедии
1С: Управление торговлей 8.2
1С: Управление торговлей 8.2

Современные торговые предприятия предлагают своим клиентам широчайший ассортимент товаров, который исчисляется тысячами и десятками тысяч наименований. Причем многие позиции могут реализовываться на разных условиях: предоплата, отсрочка платежи, скидка, наценка, объем партии, и т.д. Клиенты зачастую делятся на категории – VIP-клиент, обычный клиент, постоянный клиент, мелкооптовый клиент, и т.д. Товарные позиции могут комплектоваться и разукомплектовываться, многие товары подлежат обязательной сертификации и гигиеническим исследованиям, некондиционные позиции необходимо списывать, на складах периодически должна проводиться инвентаризация, каждая компания должна иметь свою маркетинговую политику и т.д., вообщем – современное торговое предприятие представляет живой организм, находящийся в постоянном движении.Очевидно, что вся эта кипучая деятельность требует автоматизации. Для решения этой задачи существуют специальные программные средства, и в этой книге мы познакомим вам с самым популярным продуктом, предназначенным для автоматизации деятельности торгового предприятия – «1С Управление торговлей», которое реализовано на новейшей технологической платформе версии 1С 8.2.

Алексей Анатольевич Гладкий

Финансы / Программирование, программы, базы данных