Что такое дескриптор файла
Обновлено: 04.07.2024
Для большинства операционных систем файловый дескриптор (FD) представляет собой небольшое неотрицательное целое число, помогающее идентифицировать открытый файл в процессе при использовании ресурсов ввода/вывода, таких как сетевые сокеты или каналы. В некотором смысле его можно рассматривать как индексную таблицу открытых файлов. Когда есть операции чтения, записи или закрытия файла, одним из рассматриваемых входных параметров является файловый дескриптор. Дескрипторы файлов являются важным компонентом интерфейса прикладного программирования POSIX и обеспечивают примитивный низкоуровневый интерфейс для операций ввода и вывода.
Techopedia объясняет файловый дескриптор (FD)
Ядро создает файловый дескриптор всякий раз, когда сталкивается с открытым вызовом. Во многих отношениях шлюз в абстракции ядра базового оборудования можно рассматривать как файловые дескрипторы. В операционной системе Unix стандартный ввод представлен дескриптором файла 0, стандартный вывод представлен дескриптором файла 1, а стандартный файл ошибок представлен дескриптором файла 2. Другими словами, в соответствии с тремя стандартными потоками каждый процесс UNIX будет иметь три стандартных файловых дескриптора. И потоки, и файловые дескрипторы могут представлять соединение с устройством, однако для управления конкретными устройствами необходимо использовать файловые дескрипторы. В большинстве операционных систем, таких как UNIX, дескрипторы файлов представлены как объекты типа «int». Дескриптор файла используется ядром в качестве индекса в таблице описания файлов, чтобы определить, какой процесс первоначально открыл конкретный файл, а затем разрешить выполнение запрошенных операций на открытом устройстве или файле.
С точки зрения прикладного программирования файловые дескрипторы необходимо использовать, если есть какие-либо операции ввода или вывода в специальных режимах, включая неблокирующие вводы. В отличие от потоков, которые предоставляют расширенные функции для управления, интерфейс файлового дескриптора предоставляет только простые функции для передачи блоков символов. Низкоуровневые операции можно выполнять непосредственно над файловым дескриптором.
Одна из первых вещей, которую узнают программисты UNIX, это то, что каждая работающая программа запускается с тремя уже открытыми файлами:
Описательное имя | Короткое имя | Номер файла | Описание |
---|---|---|---|
Стандартный в | stdin | 0 | Ввод с клавиатуры |
Стандартный выход | stdout | 1 | Вывод в консоль |
Стандартная ошибка | stderr | 2 | Вывод ошибки на консоль |
В связи с этим возникает вопрос о том, что представляет собой открытый файл. Значение, возвращаемое вызовом open, называется файловым дескриптором и, по сути, является индексом в массиве открытых файлов, хранимом ядром.
Реализация канала
Реализация ls | more — это еще один пример силы абстракции. В основном здесь происходит то, что вместо связывания дескриптора файла для стандартного вывода с каким-либо базовым устройством (например, консолью для вывода на терминал) дескриптор указывает на буфер в памяти, предоставленный ядром. обычно называют трубой. Хитрость здесь в том, что другой процесс может связать свой стандартный вход с другой стороной этого же буфера и эффективно использовать выходные данные другого процесса. Это показано на рис. 1.4, «Труба в действии».
Значит, это просто целое число, которое однозначно представляет открытый файл в операционной системе." Это неверно. Это целое число однозначно представляет открытый файл в процессе. Дескриптор файла 0, например, будет представлять один открытый файл в одном процессе и совершенно другой открытый файл в другом процессе.
@Tayyab: Думаю, ты ошибаешься. Файловые дескрипторы 0, 1 и 2 — это стандартный ввод, стандартный вывод и стандартная ошибка для каждого запущенного процесса. Успешный первоначальный вызов open() даст вам файловый дескриптор 3, даже если другой запущенный процесс имеет файловый дескриптор 3. См. определение POSIX для open(): «Функция open() должна возвращать файловый дескриптор для именованный файл с наименьшим файловым дескриптором, который в данный момент не открыт для этого процесса». (выделение добавлено).
@KeithThompson: Да, вы правы. На самом деле речь идет об уровне абстракции. На самом деле поддерживаются две таблицы, первая из которых предназначена для каждого процесса, а вторая — для всей системы. FD в таблице для каждого процесса (т.е. fdtable) не уникален для всей системы. Однако он сопоставляется с таблицей v-node, которая содержит уникальные записи для всей системы. Поэтому, когда вы вызываете функции fopen() и fileno() для проверки дескриптора, вы можете получить один и тот же номер FD в двух разных процессах, потому что он возвращает индекс fdtable для каждого процесса. Спасибо, что подняли тему!!
Дескриптор файла — это непрозрачный дескриптор, который используется в интерфейсе между пользователем и пространством ядра для идентификации ресурсов файла/сокета. Поэтому, когда вы используете open() или socket() (системные вызовы для взаимодействия с ядром), вам предоставляется файловый дескриптор, который является целым числом (на самом деле это индекс в структуре процессов u, но это не важно). ). Поэтому, если вы хотите напрямую взаимодействовать с ядром, используя системные вызовы read() , write() , close() и т. д., вы используете дескриптор файла.
На системные вызовы накладывается слой абстракции, которым является интерфейс stdio. Это обеспечивает больше функциональных возможностей/возможностей, чем базовые системные вызовы. Для этого интерфейса непрозрачный дескриптор, который вы получаете, представляет собой FILE* , который возвращается вызовом fopen(). Существует множество функций, использующих интерфейс stdio fprintf() , fscanf() , fclose() , которые упрощают вашу жизнь. В C stdin , stdout и stderr являются FILE* , которые в UNIX соответственно сопоставляются с файловыми дескрипторами 0 , 1 и 2 .
Услышьте это из первых уст: APUE (Ричард Стивенс).
Для ядра все открытые файлы называются файловыми дескрипторами. Дескриптор файла — это неотрицательное число.
Когда мы открываем существующий файл или создаем новый файл, ядро возвращает процессу дескриптор файла. Ядро поддерживает таблицу всех дескрипторов открытых файлов, которые используются. Распределение файловых дескрипторов обычно последовательное, и они назначаются файлу как следующий свободный файловый дескриптор из пула свободных файловых дескрипторов. Когда мы закрываем файл, дескриптор файла освобождается и становится доступным для дальнейшего выделения.
Подробнее см. на этом изображении:
Когда мы хотим прочитать или записать файл, мы идентифицируем файл с дескриптором файла, который был возвращен вызовом функции open() или create(), и используем его в качестве аргумента для чтения() или записи(). .
Согласно соглашениям, системные оболочки UNIX связывают дескриптор файла 0 со стандартным вводом процесса, дескриптор файла 1 со стандартным выводом и дескриптор файла 2 со стандартной ошибкой.
Описатель файла находится в диапазоне от 0 до OPEN_MAX. Максимальное значение дескриптора файла можно получить с помощью ulimit -n . Для получения дополнительной информации прочитайте 3-ю главу книги APUE.
Что такое файловый дескриптор?
Файловый дескриптор — это целое число, которое однозначно идентифицирует открытый файл процесса.
Таблица файловых дескрипторов. Таблица файловых дескрипторов представляет собой набор индексов целочисленного массива, представляющих собой файловые дескрипторы, элементы которых являются указателями на записи файловой таблицы. В операционной системе для каждого процесса предоставляется одна уникальная таблица файловых дескрипторов.
Запись таблицы файлов. Записи таблицы файлов представляют собой структуру в памяти для суррогата открытого файла, которая создается, когда процесс обрабатывает запрос на открытие файла, и эти записи поддерживают позицию в файле.
Стандартные файловые дескрипторы: при запуске любого процесса автоматически открывается таблица fd (файловый дескриптор) 0, 1, 2 таблицы файловых дескрипторов этого процесса (по умолчанию) (по умолчанию) каждый из этих трех файловых дескрипторов ссылается на запись в таблице файлов для файла с именем /dev. /терминал
/dev/tty: заместитель терминала в памяти
Терминал: комбинация клавиатуры и видеоэкрана
Чтение со стандартного ввода => чтение с fd 0: Всякий раз, когда мы пишем какой-либо символ с клавиатуры, он считывается со стандартного ввода через fd 0 и сохраняется в файл с именем /dev/tty.
Запись на стандартный вывод => запись в fd 1: Всякий раз, когда мы видим какой-либо вывод на видеоэкран, он поступает из файла с именем /dev/tty и записывается в стандартный вывод на экране через fd 1.
Запись в стандартный вывод => запись в fd 2: Мы видим любую ошибку в экран видео, он же из этого файла пишет в stderr в screen через fd 2.
Системные вызовы ввода/вывода
В основном существует 5 типов системных вызовов ввода/вывода:
<р>1. Создать: используется для создания нового пустого файла.- имя файла: имя файла, который вы хотите создать
- режим: указывает права доступа к новому файлу.
- возвратить первый неиспользуемый файловый дескриптор (обычно 3 при первом создании использования в процессе, потому что 0, 1, 2 fd зарезервированы)
- вернуть -1 при ошибке
- Создать новый пустой файл на диске
- Создать запись в таблице файлов
- Установить первый неиспользуемый файловый дескриптор так, чтобы он указывал на запись в таблице файлов
- Возвращает использованный файловый дескриптор, -1 в случае ошибки
Читайте также: