在我们学习Linux的过程中,对文件的输入输出接触的比较多的一个函数就是dup2函数,我们也可以用dup2函数进行重定向;
一、dup2函数的介绍
函数:
dup2(int oldfd,int newfd);
1、所包含头文件
#include<unistd.h>
2、功能
文件描述符的复制
3、返回值
成功返回新文件描述符
失败返回-1
二、文件描述符简要介绍
在文件描述符中,0、1、2被系统占用
0:表示标准输入(键盘输入)
1:表示标准输出(屏幕输出)
2:表示标准错误
所以,当我们打开一个文件时,返回的文件描述符都是大于等于3的。
当我们使用标准输入输出的时候要添加头文件
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
三、文件描述符的复制
我们知道文件描述符返回的是一个数字,数字可以复制吗?肯定是不行的,所以我们所说的文件描述符的复制是指针,这里我们以一个程序来进行说明
#include<stdio.h>
#include<fcntl.h>
#include<string.h>
#include<errno.h>
#include<sys/stat.h>
#include<sys/type.h>
#include<unistd.h>
#define BUFFER_LINE 4096
//为了实现输入输出效果,这里编写一个函数实现读写以及打印功能
void copy(int fdin,int fdout);
int main(int argc,char *argv[])
{
int fd_in,fd_out;
int i;
for(i=1;i<argc;i++)
{
fd_in = open(argv[i],O_RDONLY);
if(fd_in < 0){
perror("open error");
exit(1);
}
//这里我们可以将fd_in的值打印出来看一下,是不是和我们之前所讲的一样,大于等于3
printf("fd_in ==== %d\n",fd_in);
}
//使用dup2将标准输入改为从fd_in中输入
if(dup2(fd_in,STDIN_FILENO)!=STDIN_FILENO)
{
perror("dup2 error");
exit(1);
}
close(fd_in);
//STDIN_FILENO已经从标准输入(键盘)改为从文件输入,STDPUT_FILENO仍然是标准输出(屏幕)
copy(STDIN_FILENO,STDOUT_FILENO);
return 0;
}
//在此处进行函数实现
void copy(int fdin,int fdout)
{
char buffer[BUFFER_LINE];
ssize_t size;
while((size = read(fdin,buffer,BUFFER_LINE))>0)
{
if(write(fdout,buffer,size)!=size)
{
perror("write error");
exit(1);
}
}
if(size < 0)
{
perror("read error");
exit(1);
}
}
结果显示如下:
当我们运行该程序后,标准输出的是我们iotek.txt里面的内容
文件描述符复制过程图解
1:代表将fd_in 的指针复制到STDIN_FILENO,所以STDIN_FILENO指向的也是读取的文件
接下来,我们在写一个程序,重定向标准输出
#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
#include<sys/stat.h>
#include<sys/types.h>
#include<fcntl.h>
int main(int argc,char * [])
{
int fd_out;
fd_out = open(argv[1],O_CREAT|O_WRONLY,0777);
if(fd_out < 0)
{
perror("open error");
exit(1);
}
printf("fd_out ====== %d\n",fd_out);
//重定向标准输出 将标准输出(屏幕)重定向到fd_out
if(dup2(fd_out,STDOUT_FILENO)!=STDOUT_FILENO)
{
perror("dup2 error");
exit(1);
}
close(fd_out);
//此时printf将不会在屏幕上输出 而是会输出到fd_out所指的文件中
printf("abc");
}
结果显示如下:
从两个程序的结果可知:
文件描述符的复制过程:返回的新文件描述符一定是当前可用文件描述符中的最小数值
文章是个人在学习过程中的一些思考与理解,如果不对的地方,还请指正,必会虚心接受并加以更改!