LINUX C中stdout和STDOUT_FILENO之间的区别

Bin*_* Lu 57 c linux stdout

我想知道的区别stdout,并STDOUT_FILENO在Linux中C.

经过一番搜索工作,我得出以下结论.你能帮我复习并纠正错误吗?谢谢

  • 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.
Run Code Online (Sandbox Code Playgroud)

因此,在我看来,STDOUT_FILENO属于系统级调用,并且在某种程度上,就像系统API一样.STDOUT_FILENO可用于描述系统中的任何设备.

stdout较高的水平(用户级?)定位和实际封装的细节STDOUT_FILENO.stdout有I/O缓冲区.

这是我对他们差异的理解.任何评论或更正都表示赞赏,谢谢.

Bas*_*tch 73

stdout是一个FILE*"常数"给出标准的外出流.所以显然fprintf(stdout, "x=%d\n", x);有同样的行为printf("x=%d\n", x);; 您使用stdout<stdio.h>类似功能fprintf,fputs等等.

STDOUT_FILENO是一个整数文件描述符(实际上是整数1).您可以将它用于write系统调用.

两者之间的关系是 STDOUT_FILENO == fileno(stdout)

(除非你做了一些奇怪的事情fclose(stdout);,或者也许是一些事情freopen之后fclose(stdin),你几乎永远不会做的事情!看看这个,由JFSebastian评论)

你通常喜欢这些FILE*东西,因为它们是缓冲的(因此通常表现良好).有时,您可能想要调用fflushflush缓冲区.

您可以将文件描述符编号用于syscalls,write(2)(由stdio库使用)或poll(2).但使用系统调用是一团糟.它可能会给你非常好的效率(但这很难编码),但通常stdio库足够好(并且更便携).

(当然你应该#include <stdio.h>为stdio函数,以及#include <unistd.h>- 和一些其他标题 - 用于系统调用write.而stdio函数是用syscalls实现的,所以fprintf可以调用write).

  • `STDOUT_FILENO == fileno(stdout)`很棒,这个表达式帮助我完全理解这个问题.非常感谢.@Basile (15认同)
  • [`STDOUT_FILENO == fileno(stdout)`](http://stackoverflow.com/q/25516375/4279)——它总是正确的吗? (2认同)
  • 文件描述符对于使用“dup2”将流重定向到文件描述符表中的不同位置也很有用(例如,获取进行一些系统调用的子进程的输出并打印到“stdout”,并告诉操作系统重定向该输出在进行系统调用之前保存为文本文件) (2认同)