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 缓冲区。

这就是我对他们区别的理解。任何意见或更正表示赞赏,谢谢。

最佳答案

stdout 是一个 FILE* “常量”,给出标准输出流。所以显然 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 库已经足够好(并且更便携)。

(当然,对于 stdio 函数,您应该使用 #include <stdio.h>,而对于 #include <unistd.h> 等系统调用,您应该使用 write - 和其他一些头文件。并且 stdio 函数是通过系统调用实现的,因此 fprintf 可能会调用 write )。

https://stackoverflow.com/questions/12902627/

相关文章:

linux - 为什么 docker 有能力运行不同的 linux 发行版?

python - 如何列出导入的模块?

c++ - 如何在 Linux 上执行适用于 x86、arm、GCC 和 icc 的原子操作?

python - Numpy:从二维数组中获取随机行集

linux - 如何在复杂的文本文件中替换 shell 变量

python - 通过比较两个绝对路径获取相对路径

linux - 我应该使用什么 Linux shell?

python - 遍历python中的对象属性

python - 在 matplotlib 中设置颜色条范围

linux - 从命令行将文本附加到文件而不使用 io 重定向