Что такое дескрипторы файлов, объясненные простыми словами?
-
Что будет более упрощенным описанием файловых дескрипторов по сравнению с Википедии? Зачем они нужны? Скажем, возьмите в качестве примера процессы оболочки и как это применимо к нему?
-
В таблице процессов содержится более одного дескриптора файла. Если да, то почему?
Ответы
Ответ 1
Простыми словами при открытии файла операционная система создает запись для представления этого файла и сохраняет информацию об этом открывшемся файле. Итак, если в вашей ОС открыто 100 файлов, то в ОС будет находиться 100 записей (где-то в ядре). Эти записи представлены целыми числами типа (... 100, 101, 102....). Этот номер записи является файловым дескриптором.
Таким образом, это просто целое число, которое уникально представляет собой открытый файл в операционной системе.
Если ваш процесс откроет 10 файлов, ваша таблица процессов будет содержать 10 записей для дескрипторов файлов.
Аналогично, когда вы открываете сетевой сокет, он также представляется целым числом и называется дескриптором Socket.
Надеюсь, вы понимаете.
Ответ 2
Дескриптор файла - это непрозрачный дескриптор, который используется в интерфейсе между пространством пользователя и ядра для идентификации ресурсов файла/сокета. Поэтому, когда вы используете open()
или socket()
(системные вызовы для интерфейса с ядром), вам предоставляется дескриптор файла, который является целым числом (это фактически индекс в структуре процессов u, но это не важно). Поэтому, если вы хотите напрямую взаимодействовать с ядром, используя системные вызовы read()
, write()
, close()
и т.д. Дескриптор, который вы используете, является файловым дескриптором.
На системных вызовах имеется слой абстракции, который является интерфейсом stdio
. Это обеспечивает больше функциональности/функций, чем это делают основные системные вызовы. Для этого интерфейса непрозрачным дескриптором вы получаете FILE*
, который возвращается вызовом fopen()
. Существует много функций, которые используют интерфейс stdio
fprintf()
, fscanf()
, fclose()
, которые помогут вам сделать вашу жизнь проще. В C, stdin
, stdout
и stderr
находятся FILE*
, которые в UNIX соответственно сопоставляются файловым дескрипторам 0
, 1
и 2
.
Ответ 3
Услышь это из Лошадиной пасти: APUE (Ричард Стивенс).
В ядре все открытые файлы упоминаются дескрипторами файлов. Файловый дескриптор - это не -n число.
Когда мы открываем существующий файл или создаем новый файл, ядро возвращает файловый дескриптор процессу. Ядро поддерживает таблицу всех открытых дескрипторов файлов, которые используются. Выделение файловых дескрипторов, как правило, является последовательным, и они выделяются для файла в качестве следующего свободного файлового дескриптора из пула бесплатных файловых дескрипторов. Когда мы закрываем файл, дескриптор файла освобождается и становится доступным для дальнейшего выделения.
Смотрите это изображение для более подробной информации:
![Two Process]()
Когда мы хотим прочитать или записать файл, мы отождествляем файл с дескриптором файла, который был возвращен вызовом функции open() или create(), и используем его в качестве аргумента для read() или write().
По соглашению системные оболочки UNIX связывают дескриптор файла 0 со стандартным вводом процесса, дескриптор файла 1 со стандартным выводом и дескриптор файла 2 со стандартной ошибкой.
Дескриптор файла варьируется от 0 до OPEN_MAX. Максимальное значение дескриптора файла можно получить с помощью ulimit -n
. Для получения дополнительной информации просмотрите 3-ю главу книги APUE.
Ответ 4
В дополнение к другим ответам, unix рассматривает все как файловую систему. Ваша клавиатура - это файл, который читается только с точки зрения ядра. Экран - это файл только для записи. Аналогичным образом, папки, устройства ввода-вывода и т.д. Также считаются файлами. Всякий раз, когда файл открывается, скажите, когда драйверы устройства [для файлов устройства] запрашивают open() или процесс открывает файл пользователя, ядро выделяет файловый дескриптор, целое число, которое указывает доступ к этому файлу, такое, что оно доступно только для чтения, писать только и т.д. [для справки: https://en.wikipedia.org/wiki/Everything_is_a_file]
Ответ 5
Еще несколько пунктов относительно File Descriptor
:
-
File Descriptors
(FD) являются неотрицательными целыми числами (0, 1, 2,...)
, которые связаны с открытыми файлами.
-
0, 1, 2
- это стандартные FD, соответствующие STDIN_FILENO
, STDOUT_FILENO
и STDERR_FILENO
(определенные в unistd.h
), открытые по умолчанию от имени оболочки при запуске программы.
-
FD распределяются в последовательном порядке, что означает наименьшее возможное нераспределенное целочисленное значение.
-
FD для конкретного процесса можно увидеть в /proc/$pid/fd
(в системах на основе Unix).
Ответ 6
Другие ответы добавили отличные вещи. Я добавлю только мои 2 цента.
Согласно Википедии мы точно знаем: дескриптор файла является неотрицательным целым числом. Самая важная вещь, которую я считаю отсутствующей, это сказать:
Файловые дескрипторы привязаны к идентификатору процесса.
Мы знаем, что наиболее известные файловые дескрипторы: 0, 1 и 2. 0 соответствует STDIN
, 1 - STDOUT
, 2 - STDERR
.
Скажем, возьмем процессы оболочки в качестве примера и как это применимо к нему?
Проверьте этот код
#>sleep 1000 &
[12] 14726
Мы создали процесс с идентификатором 14726 (PID). Используя lsof -p 14726
мы можем получить такие вещи:
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
sleep 14726 root cwd DIR 8,1 4096 1201140 /home/x
sleep 14726 root rtd DIR 8,1 4096 2 /
sleep 14726 root txt REG 8,1 35000 786587 /bin/sleep
sleep 14726 root mem REG 8,1 11864720 1186503 /usr/lib/locale/locale-archive
sleep 14726 root mem REG 8,1 2030544 137184 /lib/x86_64-linux-gnu/libc-2.27.so
sleep 14726 root mem REG 8,1 170960 137156 /lib/x86_64-linux-gnu/ld-2.27.so
sleep 14726 root 0u CHR 136,6 0t0 9 /dev/pts/6
sleep 14726 root 1u CHR 136,6 0t0 9 /dev/pts/6
sleep 14726 root 2u CHR 136,6 0t0 9 /dev/pts/6
Четвертый столбец FD и следующий столбец TYPE соответствуют дескриптору файла и типу дескриптора файла.
Некоторые значения для FD могут быть:
cwd – Current Working Directory
txt – Text file
mem – Memory mapped file
mmap – Memory mapped device
Но настоящий дескриптор файла находится под:
NUMBER – Represent the actual file descriptor.
Символ после числа, т.е. "1u", представляет режим, в котором открывается файл. r для чтения, w для записи, u для чтения и записи.
TYPE указывает тип файла. Некоторые из значений типов:
REG – Regular File
DIR – Directory
FIFO – First In First Out
Но все файловые дескрипторы - это CHR - специальный символьный файл (или символьный файл устройства)
Теперь мы можем легко идентифицировать файловые дескрипторы для STDIN
, STDOUT
и STDERR
с помощью lsof -p PID
, или мы можем увидеть то же самое, если мы используем ls/proc/PID/fd
.
Также обратите внимание, что таблица файловых дескрипторов, которую отслеживает ядро, отличается от таблицы файлов или таблицы inode. Это отдельные, как объяснили некоторые другие ответы.
![fd table]()
Вы можете спросить себя, где физически находятся эти файловые дескрипторы и что, например, хранится в /dev/pts/6
sleep 14726 root 0u CHR 136,6 0t0 9 /dev/pts/6
sleep 14726 root 1u CHR 136,6 0t0 9 /dev/pts/6
sleep 14726 root 2u CHR 136,6 0t0 9 /dev/pts/6
Ну, /dev/pts/6
живет исключительно в памяти. Это не обычные файлы, а так называемые файлы символьных устройств. Вы можете проверить это с помощью: ls -l/dev/pts/6
и они начнутся с c
, в моем случае crw--w----
.
Напомним, что большинство Linux-подобных ОС определяют семь типов файлов:
- Обычные файлы
- Справочники
- Файлы символьных устройств
- Блокировать файлы устройства
- Локальные доменные сокеты
- Именованные каналы (FIFO) и
- Символьные ссылки
Ответ 7
Файловые дескрипторы (FD):
- В Linux/Unix все является файлом. Обычный файл, каталоги и даже устройства являются файлами. Каждый файл имеет связанный номер, называемый дескриптором файла (FD).
- Ваш экран также имеет дескриптор файла. Когда программа выполняется, вывод отправляется в дескриптор файла на экране, и вы видите вывод программы на вашем мониторе. Если выходные данные отправляются в дескриптор файла принтера, выходные данные программы будут напечатаны.
Перенаправление ошибок:
Всякий раз, когда вы выполняете программу/команду в терминале, всегда открыты 3 файла. - стандартный ввод
- стандартный вывод
- стандартная ошибка.
Эти файлы всегда присутствуют при запуске программы. Как объяснено ранее файловый дескриптор, связан с каждым из этих файлов.
Дескриптор файла
Стандартный вход STDIN 0
Стандартный выход STDOUT 1
Стандартная ошибка STDERR 2
- Например, при поиске файлов обычно получаются ошибки, в которых отказано в разрешении, или какие-либо другие ошибки. Эти ошибки могут быть сохранены в конкретном файле.
Пример 1
$ ls mydir 2> errorsfile.txt
Дескриптор файла для стандартной ошибки - 2.
Если нет каталога с именем mydir, вывод команды будет сохранен в файле errorfile.txt.
Используя "2>", мы перенаправляем вывод ошибок в файл с именем "errorfile.txt"
Таким образом, вывод программы не загроможден ошибками.
Я надеюсь, что вы получили свой ответ.
Ответ 8
В любой операционной системе работают процессы (p), например p1, p2, p3 и т.д. Каждый процесс обычно делает постоянное использование файлов.
Каждый процесс состоит из дерева процессов (или таблицы процессов, в другой фразировке).
Обычно операционные системы представляют каждый файл в каждом процессе по номеру (то есть в каждом дереве/таблице процессов).
Первым файлом, используемым в этом процессе, является файл0, второй - файл1, третий - файл2 и т.д.
Любое такое число является файловым дескриптором.
Дескрипторы файлов обычно являются целыми числами (0, 1, 2, а не 0,5, 1,5, 2,5).
Учитывая, что мы часто описываем процессы как "таблицы процессов" и учитывая, что в таблицах есть строки (записи), мы можем сказать, что ячейка дескриптора файла в каждой записи используется для представления всей записи.
Аналогично, когда вы открываете сетевой сокет, он имеет дескриптор сокета.
В некоторых операционных системах вы можете исчерпать дескрипторы файлов, но такой случай крайне редок, и средний пользователь компьютера не должен беспокоиться об этом.
Дескрипторы файлов могут быть глобальными (процесс A начинается с 0, и заканчивается в 1, процесс B начинается с 2, а заканчивается на 3) и т.д., но, насколько я знаю, обычно в современных операционных системы, дескрипторы файлов не являются глобальными и на самом деле зависят от процесса (процесс A начинается с 0, а заканчивается на 5, а процесс B начинается с 0, а заканчивается на 10).
Ответ 9
Файловые дескрипторы
- В ядре все открытые файлы называются файловыми дескрипторами.
- Дескриптор файла является неотрицательным целым числом.
- Когда мы открываем существующий или создаем новый файл, ядро возвращает файловый дескриптор процессу.
- Когда мы хотим прочитать или записать файл, мы идентифицируем файл с дескриптором файла, который был перенастроен open или create, в качестве аргумента для чтения или записи.
- Каждый процесс UNIX имеет 20 файловых дескрипторов и может быть удален с номерами от 0 до 19, но во многих системах он был расширен до 63.
- Первые три уже открыты, когда начинается процесс 0: Стандартный ввод 1: Стандартный вывод 2: Стандартный вывод ошибок
- Когда родительский процесс разветвляется, дочерний процесс наследует файловые дескрипторы родительского процесса.
Ответ 10
Помимо всего прочего упрощенные ответы.
Если вы работаете с файлами в bash-скрипте, лучше использовать файловый дескриптор.
Например:-
Вы хотите читать и писать из/в файл "test.txt".
Используйте дескриптор файла, как показано ниже
FILE=$1 # give the name of file in the command line
exec 5<>$FILE # '5' here act as the file descriptor
# Reading from the file line by line using file descriptor
while read LINE; do
echo "$LINE"
done <&5
# Writing to the file using descriptor
echo "Adding the date: 'date'" >&5
exec 5<&- # Closing a file descriptor
Ответ 11
Файловые дескрипторы являются дескрипторами файла. Они дают ссылки на файл. С их помощью мы можем читать, писать и открывать файл.