Что такое дескрипторы файлов, объясненные простыми словами?

  • Что будет более упрощенным описанием файловых дескрипторов по сравнению с Википедии? Зачем они нужны? Скажем, возьмите в качестве примера процессы оболочки и как это применимо к нему?

  • В таблице процессов содержится более одного дескриптора файла. Если да, то почему?

Ответ 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:

  1. File Descriptors (FD) являются неотрицательными целыми числами (0, 1, 2,...), которые связаны с открытыми файлами.

  2. 0, 1, 2 - это стандартные FD, соответствующие STDIN_FILENO, STDOUT_FILENO и STDERR_FILENO (определенные в unistd.h), открытые по умолчанию от имени оболочки при запуске программы.

  3. FD распределяются в последовательном порядке, что означает наименьшее возможное нераспределенное целочисленное значение.

  4. 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 файла.
    1. стандартный ввод
    2. стандартный вывод
    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

Файловые дескрипторы являются дескрипторами файла. Они дают ссылки на файл. С их помощью мы можем читать, писать и открывать файл.