LINUX C中stdout和STDOUT_FILENO之间的区别

时间:2012-10-15 19:26:47

标签: c linux stdout

我想知道Linux C中stdoutSTDOUT_FILENO之间的区别。

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

  • stdout属于C语言的标准I / O流;其类型为FILE *并在stdio.h中定义

  • 拥有int类型的
  • STDOUT_FILENOunistd.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缓冲区。

这是我对他们差异的理解。感谢任何评论或更正。

1 个答案:

答案 0 :(得分:69)

stdoutFILE*“常量”,提供标准的输出流。显然fprintf(stdout, "x=%d\n", x);printf("x=%d\n", x);具有相同的行为;您对stdout函数使用<stdio.h>,例如fprintffputs等。

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

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

(除非您执行fclose(stdout);之类的奇怪内容,或者某些freopen之后的某些fclose(stdin)之后,您几乎永远不会这样做!请参阅this,由J.F.Sebastian)评论

您通常更喜欢FILE*项内容,因为它们是缓冲的(因此通常表现良好)。有时,您可能希望调用fflush来刷新缓冲区。

您可以使用syscalls的文件描述符编号,例如write(2)(由stdio库使用)或poll(2)。但使用系统调用是一团糟。它可以为您提供非常好的效率(但这很难编码),但stdio库通常足够好(并且更便于移植)。

(当然你应该#include <stdio.h>用于stdio函数,#include <unistd.h>write - 和其他一些标题 - 用于像fprintf这样的系统调用。而stdio函数用syscalls实现,所以write可以致电{{1}})。