Подтвердить что ты не робот

Разница между stdout и STDOUT_FILENO в LINUX C

Мне было интересно узнать разницу между stdout и STDOUT_FILENO в Linux C.

После некоторой поисковой работы я делаю следующий вывод. Не могли бы вы помочь мне просмотреть его и исправить любую ошибку? Благодаря

  • stdout относится к стандартным потокам ввода-вывода языка C; тип которого FILE * и определен в stdio.h

  • STDOUT_FILENO, обладающий типом int, определяется в unistd.h. Это файловый дескриптор системы LINUX. В unistd.h он объясняется следующим образом:

The following symbolic constants shall be defined for file streams:

STDERR_FILENO
    File number of stderr; 2.
STDIN_FILENO
    File number of stdin; 0.
STDOUT_FILENO
    File number of stdout; 1.

Итак, на мой взгляд, STDOUT_FILENO принадлежит системному вызову и, в некоторой степени, как системный API. STDOUT_FILENO может использоваться для описания любого устройства в системе.

stdout находится на более высоком уровне (пользовательский уровень?) и фактически инкапсулирует детали STDOUT_FILENO. stdout имеет буфер ввода/вывода.

Что я понимаю об их различии. Любые комментарии или исправления приветствуются, спасибо.

4b9b3361

Ответ 1

stdout является константой FILE* ", предоставляющей стандартный выходной поток. Таким образом, очевидно, что fprintf(stdout, "x=%d\n", x); имеет такое же поведение, как printf("x=%d\n", x);; вы используете stdout для <stdio.h> функций типа fprintf, fputs и т.д.

STDOUT_FILENO - целочисленный файловый дескриптор (фактически, целое число 1). Вы можете использовать его для write syscall.

Соотношение между ними STDOUT_FILENO == fileno(stdout)

(За исключением случаев, когда вы делаете странные вещи типа fclose(stdout); или, возможно, некоторые freopen после некоторого fclose(stdin), которые вы почти никогда не должны делать! См. this, как прокомментировал JFSebastian)

Обычно вы предпочитаете вещи FILE*, потому что они буферизованы (как правило, хорошо работают). Иногда вы можете вызвать fflush для сброса буферов.

Вы можете использовать номера дескрипторов файлов для syscalls, например write ( 2) (который используется библиотекой stdio), или poll (2). Но использование системных вызовов является clumpsy. Это может дать вам очень хорошую эффективность (но это сложно скопировать), но очень часто библиотека stdio достаточно хороша (и более портативна).

(Конечно, вы должны #include <stdio.h> для функций stdio и #include <unistd.h> - и некоторых других заголовков - для системных вызовов, таких как write. И функции stdio реализованы с помощью системных вызовов, поэтому fprintf может вызывать write).