Книга: Linux программирование в примерах
4.4.1. Понятие о дескрипторах файлов
4.4.1. Понятие о дескрипторах файлов
Дескриптор файла является целым значением. Действительные дескрипторы файлов начинаются с 0 и растут до некоторого установленного системой предела. Эти целые фактически являются индексами таблицы открытых файлов для каждого процесса (Таблица поддерживается внутри операционной системы; она недоступна запущенным программам.) В большинстве современных систем размеры таблиц большие. Команда 'ulimit -n
' печатает это значение:
$ ulimit -n
1024
Из С максимальное число открытых файлов возвращается функцией getdtablesize()
(получить размер таблицы дескрипторов):
#include <unistd.h> /* Обычный */
int getdtablesize(void);
Следующая небольшая программа выводит результат работы этой функции:
/* ch04-maxfds.с --- Демонстрация getdtablesize(). */
#include <stdio.h> /* для fprintf(), stderr, BUFSIZ */
#include <unistd.h> /* для ssize_t */
int main(int argc, char **argv) {
printf("max fds: %dn", getdtablesize());
exit(0);
}
Неудивительно, что после компиляции и запуска эта программа выводит то же значение, что и ulimit
:
$ ch04-maxfds
max fds: 1024
Дескрипторы файлов содержатся в обычных переменных int
; для использования с системными вызовами ввода/вывода можно увидеть типичные объявления вида 'int fd
'. Для дескрипторов файлов нет предопределенного типа.
В обычном случае каждая программа начинает свою работу с тремя уже открытыми для нее дескрипторами файлов. Это стандартный ввод, стандартный вывод и стандартная ошибка, с дескрипторами файлов 0, 1 и 2 соответственно. (Если не было использовано перенаправление, каждый из них связан с клавиатурой и с экраном.)
Очевидные символические константы. Оксюморон?
При работе с системными вызовами на основе дескрипторов файлов и стандартных ввода, вывода и ошибки целые константы 0, 1 и 2 обычно используются прямо в коде. В подавляющем большинстве случаев использование таких символических констант (manifest constants) является плохой мыслью. Вы никогда не знаете, каково значение некоторой случайной целой константы и имеет ли к ней какое-нибудь отношение константа с тем же значением, использованная в другой части кода. С этой целью стандарт POSIX требует объявить следующие именованные константы (symbolic constants) в <unistd.h>
:
STDIN_FILENO
«Номер файла» для стандартного ввода: 0.
STDOUT_FILENO
Номер файла для стандартного вывода: 1.
STDERR_FILENO
Номер файла для стандартной ошибки: 2.
Однако, по нашему скромному мнению, использование этих макросов избыточно. Во-первых, неприятно набирать 12 или 13 символов вместо 1. Во-вторых, использование 0, 1 и 2 так стандартно и так хорошо известно, что на самом деле нет никаких оснований для путаницы в смысле этих конкретных символических констант.
С другой стороны, использование этих констант не оставляет сомнений в намерениях программиста. Сравните это утверждение:
int fd = 0;
Инициализируется ли fd
значением стандартного ввода, или же программист благоразумно инициализирует свои переменные подходящим значением? Вы не можете этого сказать.
Один из подходов (рекомендованный Джеффом Колье (Geoff Collyer)) заключается в использовании следующего определения enum
:
enum { Stdin, Stdout, Stderr };
Затем эти константы можно использовать вместо 0, 1 и 2. Их легко читать и печатать.
- 4.4. Ввод и вывод
- Резервное копирование многофайловых баз данных
- Восстановление из резервных копий многофайловых баз данных
- Создание файлов с блокировкой
- Понятие об ODS
- Рекомендуемое расширение для файлов баз данных - *.ib
- 1.2. Понятие информации. Общая характеристика процессов сбора, передачи, обработки и накопления информации
- Создание многофайловой базы данных
- 1.1. Понятие рекламного права и рекламного законодательства
- Правила именования файлов
- 5. Понятие ключей
- 5. Понятие индексов