web-dev-qa-db-ja.com

LINUX CのstdoutとSTDOUT_FILENOの違い

Linux CのstdoutSTDOUT_FILENOの違いに疑問を感じていました。

いくつかの検索作業の後、次の結論を導き出します。それを確認し、間違いを修正するのを手伝ってもらえますか?ありがとう

  • stdoutは、C言語の標準I/Oストリームに属します。タイプが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にはI/Oバッファーがあります。

それが彼らの違いについての私の理解です。コメントや修正は大歓迎です。

55
Bing Lu

stdoutは、標準出力ストリームを提供するFILE*「定数」です。したがって、明らかにfprintf(stdout, "x=%d\n", x);printf("x=%d\n", x);と同じ動作をします。 stdoutfprintfなどの<stdio.h>関数にはfputsを使用します。

STDOUT_FILENOは整数ファイル記述子(実際には整数1)です。 write syscallに使用できます。

2つの間の関係はSTDOUT_FILENO == fileno(stdout)です

fclose(stdout);のような奇妙なことをした後、またはfclose(stdin)の後のfreopenを除いて、ほとんどすべきではない!( this 、コメント( JFSebastian

通常、FILE*の方が好まれます。なぜなら、それらはバッファリングされているからです(したがって、通常はうまく機能します)。場合によっては、fflushを呼び出してバッファをフラッシュすることもできます。

syscalls のファイル記述子番号を使用できます write(2)stdioライブラリで使用されます)、または poll(2) 。しかし、syscallsの使用は扱いにくいです。効率は非常に優れています(ただし、コーディングは困難です)が、ほとんどの場合、stdioライブラリで十分です(さらに移植性があります)。

(もちろん、stdio関数の場合は#include <stdio.h>writeなどのシステムコールの場合は#include <unistd.h>およびその他のヘッダーを使用する必要があります。また、stdio関数はsyscallで実装されるため、fprintfwrite)。

72