, которая загружает содержимое файла в несколько несвязанных областей памяти. Как и в функции
writev
, массив структур типа iovec определяет начало и размер каждой области.
Б.4. Взаимосвязь с библиотечными функциями ввода-вывода
Выше уже говорилось о том. что функции ввода-вывода стандартной библиотеки языка С реализованы на основе низкоуровневых функций. Иногда удобнее работать с одними, иногда — с другими.
Если файл был открыт с помощью функции
fopen
, то узнать его дескриптор позволяет функция
fileno
. Она принимает аргумент типа
FILE*
и возвращает соответствующий ему дескриптор. Например, можно открыть файл с помощью библиотечной функции
fopen
, но осуществить в него запись посредством функции
writev
:
FILE* stream = fopen(filename, "w");
int file_descriptor = fileno(stream);
writev(file_descriptor, vector, vector_length);
Учтите, что переменные
stream
и
file_descriptor
соответствуют одному и тому же открытому файлу. Если выполнить следующую функцию, дескриптор
file_descriptor
станет недействительным:
fclose(stream);
Аналогичным образом следующая функция делает недействительным файловый указатель
stream
:
close(file_descriptor);
Чтобы получить файловый указатель, соответствующий дескриптору, воспользуйтесь функцией
fdopen
. Ее аргументами является дескриптор и строка, определяющая режим создания файлового потока.
Синтаксис строки аналогичен синтаксису второго аргумента функции
fopen
, а задаваемый режим должен быть совместим с режимом открытия файла. Например, файлу, открытому для чтения, соответствует режим
r
, а файлу, открытому для записи, — режим
w
. Как и в случае функции
fileno
, файловый указатель и дескриптор ссылаются на один и тот же файл, поэтому закрытие одного сделает недействительным другой.
Б.5. Другие низкоуровневые операции
Есть ряд других полезных функций для работы с файлами и каталогами.
■ Функция
getcwd
возвращает имя текущего каталога. Она принимает два аргумента — указатель на буфер и длину буфера — и копирует имя каталога в буфер.
■ Функция
chdir
делает текущим заданный каталог.
■ Функция
mkdir
создает новый каталог. Ее первым аргументом является путевое имя каталога. Второй аргумент задает права доступа к каталогу. Интерпретация этого аргумента такая же, как и третьего аргумента функции
open
. На итоговый код доступа влияет значение
umask
процесса.
■ Функция
rmdir
удаляет указанный каталог.
■ Функция
unlink
удаляет файл. Ее аргументом является путевое имя файла. С помощью этой функции можно удалять и другие объекты файловой системы, например именованные каналы и файлы устройств.
В действительности функция
unlink
не обязательно удаляет содержимое файла. Как подсказывает ее имя, она удаляет из каталога ссылку на файл. Файл не будет больше фигурировать в списке содержимого каталога, но если какой-то процесс владеет открытым дескриптором этого файла, то содержимое файла не удаляется с диска. Это произойдет только тогда, когда не останется открытых дескрипторов файла. Так что если один процесс откроет файл для чтения или записи, а второй процесс в это время удалит ссылку на файл и создаст новый файл с таким же именем, первый процесс продолжит работать со старым содержимым файла. Чтобы получить доступ к новому содержимому первому процессу придется закрыть и повторно открыть файл.
■ Функция
rename
переименовывает или перемещает файл. Двумя ее аргументами являются старое и новое путевые имена. Если путевые имена ссылаются на разные каталоги, функция перемещает файл (при условии, что он остается в той же файловой системе). С помощью функции
rename
можно перемещать также каталоги и другие объекты файловой системы.
Б.6. Чтение содержимого каталога
В Linux имеются функции, предназначенные для чтения содержимого каталога. И хотя они не относятся к низкоуровневым функциям, мы все же решили их описать, так как они широко применяются в программах.
При чтении содержимого каталога необходимо придерживаться такой последовательности действий.
1. Вызовите функцию
opendir
, передав ей путевое имя требуемого каталога. Эта функция возвращает дескриптор типа
DIR*
, который можно использовать для доступа к содержимому каталога. В случае ошибки возвращается
NULL
.
2. Последовательно вызывайте функцию
readdir
, передавая ей дескриптор, полученный от функции
opendir
. Всякий раз функция
readdir
будет возвращать указатель на структуру типа
dirent
, содержащую информацию о следующем элементе каталога. По достижении конца каталога будет получено значение