在Windows系统中,stdin和stdout文件位于何处?

6
每当我执行一个C程序时,都会有3个标准文件,stdin、stdout、stderr。这些在Linux中映射到/proc/self/fd/0、/proc/self/fd/1和/proc/self/fd/2,它们连接到我的计算机上的/dev/pts/0。这是一个伪终端,该进程向其输出并从其中输入。
在Windows中,这个等价物是什么?当我在Windows中执行相同的程序时,stdin、stdout和stderr指向哪里?

5
我不认为Windows通过类似Linux的伪文件系统提供对它们的访问,但我不确定。你为什么需要它们?你想做什么? - Ted Lyngmo
@TedLyngmo 回答我为什么需要它们,我的想法是,如果 C 标准没有提供 stdX ,那么如何输入和显示输出。在 Linux 中,可以通过打开 /dev/pts/0/dev/tty 文件来完成此操作。在 Windows 中,有什么解决方案? - Sourav Kannantha B
如何输入和显示输出?但是,你已经有 stdinstdoutstderr 了。 - Ted Lyngmo
@TedLyngmo 我说的是,如果 C 标准没有提供 stdinstdoutstderr,那么... - Sourav Kannantha B
标准输入(stdin)、标准输出(stdout)和标准错误(stderr),以及它们基于的整数fd 0、1和2,早在/proc/self/fd出现之前就已经存在了。后者是一种方便(而且非常方便!),但它并不是实现标准文件描述符概念的基础。 - Steve Summit
3个回答

7
在Linux内核上,stdinstdoutstderr流在/proc中有相应的条目。该/proc文件系统是提供对系统可见性的信息结构;它不是这些流的实现。
首先,stdout是C语言的一个概念:一个FILE * I/O流的实例。操作系统内核(无论是Linux还是Windows)对此一无所知。这些流持有操作系统文件描述符/句柄。由于链接到C库,Linux或Windows程序具有stdout流,而非C编写的程序或使用C运行时的C基础语言则可能不具备。
类Unix操作系统中的进程具有编号的文件描述符,从零开始。按照惯例,前三个——0、1和2——分别为输入、输出和错误。
在Microsoft Windows中,也有类似的概念。进程有三个HANDLE类型的句柄,用于同样的目的。当您使用CreateProcess创建进程时,它们在STARTUPINFO结构中指定,该结构具有以下成员:
HANDLE hStdInput;
HANDLE hStdOutput;
HANDLE hStdError;

如果指定了STARTF_USESTDHANDLES标志,则这些意义重大。
微软Windows没有一个/proc文件系统。它有基于API的机制来检测各种系统状态,系统实用程序是针对这些API编写的。例如,Handle程序可用于检查哪些进程打开了哪些文件。类似的Linux应用程序将在幕后遍历/proc

如果假设C标准不提供stdinstdout,那么如何输入和显示输出。在Linux中,可以通过打开/dev/pts/0/dev/tty文件来完成。在Windows中,该怎么处理呢? - Sourav Kannantha B
如果您不使用C库,或者根本不使用C语言,则无需打开任何 /dev/ 设备。您拥有文件描述符0、1和2,这些描述符是由父进程设置并继承的。Windows程序同样可以从 CreateProcess 中接收到这三个句柄,或者至少是可选的。 - Kaz
1
在Windows中,您可以使用函数GetStdHandle来获取传递给进程的三个句柄中的任何一个。因此,不需要C库,只需使用kernel32.lib中的这些函数即可。 - Kaz

2

它们在Windows上不存在文件形式。尽管Windows NT内核中有一个对象管理器,其中存在命名内核对象,但控制台并不是其中的一部分。

在Win32层,这些3个句柄是由GetStdHandle返回的。它们是特殊句柄,当调用WriteFile/ReadFile时,会检查这些特殊句柄,并在内部重新路由请求到控制台API。另一方面,如果一个标准句柄被重定向,那么句柄可以是磁盘上的真实文件或者是一个管道,正常的I/O操作将被执行。CONCONIN$CONOUT$CreateFile已知的特殊名称,并提供对控制台屏幕缓冲区的访问,但这与来自GetStdHandle的句柄并不完全相同。

C运行时库位于Win32之上,并提供另一层抽象。在内部,它将具有映射到/从std、FILE*和本机Win32句柄的函数。


0

/dev/stdin和其他Unix伪文件没有直接的等价物。

您可以创建一个命名管道(CreateNamedPipe),但它并不完全相同。

Windows文件conIN$和conOUT$类似,但它们只读取或写入当前窗口。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接