web-dev-qa-db-fra.com

La différence entre stdout et STDOUT_FILENO dans LINUX C

Je me demandais la différence entre stdout et STDOUT_FILENO sous Linux C.

Après quelques recherches, je tire la conclusion suivante. Pourriez-vous m'aider à l'examiner et à corriger toute erreur? Merci

  • stdout appartient au flux d'E/S standard en langage C; dont le type est FILE * et défini dans stdio.h

  • STDOUT_FILENO, possédant un type int, est défini à unistd.h. C'est un descripteur de fichier du système LINUX. Dans unistd.h, c'est expliqué ci-dessous:

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.

Donc, à mon avis, le STDOUT_FILENO appartient aux appels système et, dans une certaine mesure, à une API système. STDOUT_FILENO peut être utilisé pour décrire n’importe quel périphérique du système.

Le stdout se situe à un niveau supérieur (niveau utilisateur?) Et encapsule les détails de STDOUT_FILENO. stdout possède un tampon d'E/S.

C'est ce que j'ai compris de leur différence. Tout commentaire ou correction est apprécié, merci.

55
Bing Lu

stdout est une "constante" FILE* donnant le flux de sortie standard. Donc, évidemment fprintf(stdout, "x=%d\n", x); a le même comportement que printf("x=%d\n", x);; vous utilisez stdout pour <stdio.h> des fonctions telles que fprintf, fputs etc ..

STDOUT_FILENO Est un descripteur de fichier entier (en réalité, le nombre entier 1). Vous pouvez l'utiliser pour write syscall.

La relation entre les deux est STDOUT_FILENO == fileno(stdout)

(Sauf après avoir fait des choses étranges comme fclose(stdout);, ou peut-être un certain freopen après un certain fclose(stdin), ce que vous ne devriez presque jamais faire! Voir this =, commenté par JFSebastian )

Vous préférez généralement les éléments FILE*, Car ils sont en mémoire tampon (ils fonctionnent donc généralement bien). Parfois, vous voudrez peut-être appeler fflush pour vider les mémoires tampons.

Vous pouvez utiliser les numéros de descripteur de fichier pour appels système comme write (2) (utilisé par la bibliothèque stdio), ou poll (2) ) . Mais utiliser syscalls est encombrant. Cela peut vous donner une très bonne efficacité (mais c'est difficile à coder), mais très souvent, la bibliothèque stdio est suffisante (et plus portable).

(Bien sûr, vous devriez #include <stdio.h> Pour les fonctions stdio, et #include <unistd.h> -Et quelques autres en-têtes- pour les appels système comme write. Et les fonctions stdio sont implémentées avec des appels système, donc fprintf peut appeler write).

72