输入输出重定向
参与Helper2416开发板助学计划心得
通常在命令行中我们可以通过”>”运算符把标准输出重定向到文件:
如前面文件编程中所提到的,标准输出是三大默认的数据流.他们在程序运行时就会被打开,在进程中,文件描述符与数据流是相互对应的,他的对应关系就记录在文件描述表中,如下图所示:
那么我们要如何在自己的程序中使用重定向呢?
从上图来看,只要修改文件描述符表中的对应关系,替换数据流,就可以轻松的完成重定向的工作,.
从前面的文件编程中可以知道,描述符表的前三项是固定不变的..即:
0à标准输入
1à标准输出
2à标准错误
那么要完成输出重定向,就是让文件描述符1指向其他的数据流。
首先我们需要知道需要重定向到数据流的文件描述,如果我们是使用open系统调用打开文件,则直接返回的就是与文件相对应的文件描述符,但是如果是使用标准库函数fopen打开的文件的话,就还需要如下这条函数来获取数据流的描述符:
fileno()返回文件描述符
函数原型: int _fileno( FILE *stream );
函数功能: fileno()用来取得参数stream指定的文件流所使用的文件描述符
函数返回: 某个数据流的文件描述符
参数说明: stream指定文件流
所属文件:
既然已经获取到了文件描述符了,接下来就是修改文件描述符表中的对应关系了,可以通过以下系统调用改变对应关系:
dup2()复制数据流
函数原型: int dup2(int oldhandle,int newhandle);
函数功能: 复制文件描述符,实现通过多个文件描述符访问同一文件
函数返回: 成功返回0
参数说明: oldhandle指定当前的文件描述符,newhandle指定新的文件描述符用于访问oldhandle所指定的文件。
所属文件:
接下来通过实验验证是否重定向成功:
内容:把printf函数打印出的内容重定向到文件msg.txt.
实验代码:
- #include <unistd.h> // include dup2()
- #include <stdio.h> // include printf()/fprintf()/fopen()
- #include <stdlib.h> // include exit()
- #include <errno.h> // include errno
- #include <string.h> // include strerror()
-
- void error(char *msg)
- {
- fprintf(stderr, "%s: %s\n",msg,strerror(errno));
- exit(1);
- }
-
- int main()
- {
- int filedes;
- FILE *fp = fopen("msg.txt", "w");
- if(!fp){
- error("Can't open msg.txt !\n");
- }
- filedes = fileno(fp);
- dup2(filedes, 1);
-
- printf("hello world !\n");
-
- return 0;
- }
运行结果:
- [Linux@CentOS dup]$ gcc dup.c -o dup
- [Linux@CentOS dup]$ ./dup
- [Linux@CentOS dup]$ ls
- dup dup.c msg.txt
- [Linux@CentOS dup]$ cat msg.txt
- hello world !
- [Linux@CentOS dup]$
实验结果表示重定向成功,我们不仅可以重定向标准输入输出,还可以按照自己的需求,自由的重定向任意数据流,实现原理都是一样的。
论坛ID:yuanlai2010
发表时间:2014-08-12
本帖最后由 yuanlai2010 于 2014-8-12 12:15 编辑