Б.1.5. Перемещение по файлу

Б.1.5. Перемещение по файлу

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

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

? Если третий аргумент равен SEEK_SET, функция lseek() интерпретирует второй аргумент как смещение (в байтах) от начала файла.

? Если третий аргумент равен SEEK_CUR, функция lseek() интерпретирует второй аргумент как смещение (положительное или отрицательное) от текущей позиции.

? Если третий аргумент равен SEEK_END, функция lseek() интерпретирует второй аргумент как смещение (в байтах) от конца файла.

Функция lseek() возвращает смещение новой позиции от начала файла. Тип этого значения — off_t. В случае ошибки возвращается -1. Функция неприменима к файлам некоторых типов, например к сокетам.

Если требуется узнать текущую позицию файла, задайте смещение 0:

off_t position = lseek(free_descriptor, 0, SEEK_CUR);

ОС Linux позволяет перемещать указатель текущей позиции за пределы файла. Обычно, если текущая позиция находится за концом файла и выполняется операция записи, операционная система автоматически увеличивает файл, чтобы вместить в него новые данные. "Промежуток" между старым признаком конца файла и указателем текущей позиции не записывается на диск. Linux лишь помечает его длину. Если впоследствии попытаться прочесть файл, окажется, что данный промежуток заполнен нулевыми байтами.

Благодаря данной особенности функции lseek() можно создавать файлы огромного размера, практически не занимающие места на диске. Это продемонстрировано в листинге Б.5. В качестве аргументов командной строки программа принимает имя файла и требуемый размер в мегабайтах. Программа создает файл, перемещается с помощью функции lseek() на нужное расстояние и записывает нулевой байт, после чего закрывает файл.

Листинг Б.5. (lseek-huge.c) Создание огромных файлов с помощью функции lseek()

#include <fcntl.h>

#include <stdlib.h>

#include <sys/stat.h>

#include <sys/types.h>

#include <unistd.h>

int main (int argc, char* argv[]) {

 int zero = 0;

 const int megabyte = 1024 * 1024;

 char* filename = argv[1];

 size_t length = (size_t)atoi(argv[2]) * megabyte;

 /* Создание нового файла. */

 int fd = open(filename, O_WRONLY | O_CREAT | O_EXCL, 0666);

 /* Перемещение в точку, где должен быть записан последний байт

    файла. */

 lseek(fd, length - 1, SEEK_SET);

 /* Запись нулевого байта. */

 write(fd, &zero, 1);

 /* Конец работы. */

 close(fd);

 return 0;

}

Давайте теперь создадим файл размером 1 Гбайт. Обратите внимание на объем свободного места на диске до и после выполнения программы.

% df -h .

Filesystem Size Used Avail Use% Mounted on

/dev/hda5  2.9G 2.1G  655M  76% /

% ./lseek-huge bigfile 1024 % ls -l bigfile

-rw-r----- 1 samuel samuel 1073741824 Feb 5 16:29 bigfile

% df -h .

Filesystem Size Used Avail Use% Mounted on

/dev/hda5  2.9G 2.1G  655M  76% /

Как видите, файл практически не занимает место на диске, несмотря на свой огромный размер. Но если открыть его и попытаться прочитать данные, окажется, что в нем находится 1 Гбайт нулей. Давайте, к примеру, проверим это с помощью программы hexdump:

% ./hexdump bigfile / head -10

0x000000 : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

0x000010 : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

0x000020 : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

0x000030 : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

0x000040 : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

0x000050 : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

...

Чтобы не наблюдать, как по экрану проносятся 230 нулей, нажмите <Ctrl+C>.

"Волшебные промежутки" в файлах являются особенностью файловых систем типа ext2, обычно создаваемых на жестких дисках Linux. Если попытаться с помощью программы lseek-huge создать файл в файловой системе типа fat или vfat, то он займет весь указанный объем диска.

ОС Linux не позволяет функции lseek() ставить указатель текущей позиции перед началом файла.

Поделитесь на страничке

Следующая глава >

Похожие главы из других книг

4.6 НАЗНАЧЕНИЕ ИНДЕКСА НОВОМУ ФАЙЛУ

Из книги Архитектура операционной системы UNIX автора Бах Морис Дж

4.6 НАЗНАЧЕНИЕ ИНДЕКСА НОВОМУ ФАЙЛУ Для выделения известного индекса, то есть индекса, для которого предварительно определен собственный номер (и номер файловой системы), ядро использует алгоритм iget. В алгоритме namei, например, ядро определяет номер индекса, устанавливая


Применение сценария к звуковому файлу

Из книги Sound Forge 9 автора Квинт Игорь

Применение сценария к звуковому файлу Чтобы применить уже имеющийся сценарий из тех, что поставляются вместе с программой, к звуковому файлу, необходимо сделать следующее.1. Открыть нужный звуковой файл в программе, выполнив команду File ? Open (Файл ? Открыть).2. Выделить весь


7.4. Путь к файлу

Из книги Самоучитель работы на компьютере автора Колисниченко Денис Николаевич

7.4. Путь к файлу Путь задает «маршрут» к файлу. Предположим, что у нас есть простенькое дерево каталогов: корневой каталог, каталог А, подкаталог Б, в котором находится файл foto.jpg. Путь к этому файлу будет выглядеть так:АБИногда нужно указать полное имя файла. Оно состоит из


13.4.2. Закрытие доступа к файлу паролем

Из книги TCP/IP Архитектура, протоколы, реализация (включая IP версии 6 и IP Security) автора Фейт Сидни М

13.4.2. Закрытие доступа к файлу паролем Документы, содержащие конфиденциальную информацию, принято защищать паролем. Для этого в окне Сохранение документа нажмите кнопку Сервис и из появившегося меню выберите команду Параметры безопасности (рис. 127). Рис. 127. Выберите


2.4.12 Диалог для доступа к файлу

Из книги Программирование на языке Ruby [Идеология языка, теория и практика применения] автора Фултон Хэл

2.4.12 Диалог для доступа к файлу Рассмотрим последний диалог с пользователем. В этом примере используется компьютер с дисковой операционной системой (Disk Operating System — DOS), подключенный к сети TCP/IP. Мы переключимся на устройство d: локального хоста и просмотрим содержимое


10.1.4. Прямой доступ к файлу

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

10.1.4. Прямой доступ к файлу Для чтения из файла в произвольном порядке, а не последовательно, можно воспользоваться методом seek, который класс File наследует от IO. Проще всего перейти на байт в указанной позиции. Номер позиции отсчитывается от начала файла, причем самый первый


11.1.1. Права доступа к файлу

Из книги VBA для чайников автора Каммингс Стив

11.1.1. Права доступа к файлу Каждый из этих трех разрядов доступа представляет права для разных классов пользователей. Первый разряд — это права владельца файла, второй — права пользователей, входящих в группу, к которой относится файл, а последний разряд представляет


11.3.4. Изменение прав доступа к файлу

Из книги Самоучитель работы на Macintosh автора Скрылина Софья

11.3.4. Изменение прав доступа к файлу Права доступа и модификаторы прав доступа к файлу изменяются с помощью системного вызова chmod().#include <sys/stat.h>int chmod(const char *pathname, mode_t mode);int fchmod(int fd, mode_t mode);Хотя chmod() позволяет указать путь, помните, что права доступа к файлу определяет inode, а


Выбора режима доступа к файлу

Из книги Программирование для Linux. Профессиональный подход автора Митчелл Марк

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


1.7.1. Путь доступа к файлу

Из книги Операционная система UNIX автора Робачевский Андрей М.

1.7.1. Путь доступа к файлу Путь доступа к файлу представляет собой перечень имен папок, вложенных друг в друга, которые надо последовательно открыть, чтобы добраться до требуемого файла. Система Mac OS X в качестве разделителя использует два символа.? В окне свойств любого


5.3.3. Совместный доступ к файлу

Из книги Linux и UNIX: программирование в shell. Руководство разработчика. автора Тейнсли Дэвид

5.3.3. Совместный доступ к файлу Процессы могут взаимодействовать друг с другом через области отображаемой памяти, связанные с одним и тем же файлом. Если в функции mmap() указать флаг MAP_SHARED, все данные, заносимые в отображаемую память, будут немедленно записываться в файл, т.е.


Блокирование доступа к файлу

Из книги автора

Блокирование доступа к файлу Традиционно архитектура файловой подсистемы UNIX разрешает нескольким процессам одновременный доступ к файлу для чтения и записи. Хотя операции записи и чтения, осуществляемые с помощью системных вызовов read(2) или write(2), являются атомарными, в


1.4. Изменение прав доступа к файлу

Из книги автора

1.4. Изменение прав доступа к файлу Вы можете изменять режим доступа к файлам, которыми владеете, с помощью команды chmod. Аргументы этой команды могут быть заданы либо в числовом виде (абсолютный режим), либо в символьном (символьный режим). Сначала рассмотрим символьный


17.1. Проверка прав доступа к файлу

Из книги автора

17.1. Проверка прав доступа к файлу Основные форматы команды test:test условиеили[ условие ]Обратите внимание, что с обеих сторон от условия обязательно остаются пробелы. При проверке права на доступ к файлу может применяться довольно много условий. В табл. 17.1 содержится


18.3.7. Проверка прав доступа к файлу

Из книги автора

18.3.7. Проверка прав доступа к файлу Вы можете также осуществлять контроль прав доступа к файлу. Ниже приводится несложная проверка на предмет того, можно ли вести записи в файле test.txt, который переприсвоен переменной logfile.$ pg ifwr#!/bin/sh# ifwrLOGFILE=test.txt echo $LOGFILEif [ ! —w "$LOGFILE" ]; thenecho " You