stdin是标准输入,stdout是标准输出,stderr是标准错误输出。
大多数的命令行程序从stdin输入,输出到stdout或stderr,有时我们需要重定向stdout,stderr,stdin。比如:将输出写入文件,又或者我们要将命令行程序输出结果显示到Windows对话框中。
在Windows编程中,重定向需要用到管道(Pipe)的概念。管道是一种用于在进程间共享数据的机制。一个管道类似于一个管子的两端,一端是写入的,一端是读出的。由一个进程从写入端写入、另一个进程从读出端读出,从而实现通信,就向一个“管道”一样。
重定向的原理是:
首先声明两个概念:主程序(重定向的操纵者)、子进程(被重定向的子进程)
如果要重定位stdout的话,先生成一个管道, 管道的写入端交给子进程去写,主程序从管道的读出端读数据,然后可以把数据写成文件、显示等等。重定向stderr和stdout是相同的。
同理,要重定向stdin的话,生成一个管道, 管道的写入端由主程序写,子进程从管道的读出端读数据。
其中需要用到几个Windows API : CreatePipe, DuplicateHandle, CreateProcess, ReadFile, WriteFile 等,函数详解可参见MSDN.
一、编程实现原理 ( C语言)
#include
//定义句柄: 构成stdin管道的两端句柄
HANDLE hStdInRead; //子进程用的stdin的读入端
HANDLE hStdInWrite; //主程序用的stdin的读入端
//定义句柄: 构成stdout管道的两端句柄
HANDLE hStdOutRead; ///主程序用的stdout的读入端
HANDLE hStdOutWrite; ///子进程用的stdout的写入端
//定义句柄: 构成stderr管道的句柄,由于stderr一般等于stdout,我们没有定义hStdErrRead,直接用hStdOutRead即可
HANDLE hStdErrWrite; ///子进程用的stderr的写入端
//定义一个用于产生子进程的STARTUPINFO结构体 (定义见CreateProcess,函数说明)
STARTUPINFO siStartInfo;
//定义一个用于产生子进程的PROCESS_INFORMATION结构体 (定义见CreateProcess,函数说明)
PROC