Linux系统编程之文件描述符的复制:dup()和dup2()
dup()和dup2()是两个非常有用的系统调用,都是用来复制一个文件的描述符,使新的文件描述符也标识旧的文件描述符所标识的文件。
这个过程类似于现实生活中的配钥匙,钥匙相当于文件描述符,锁相当于文件,本来一个钥匙开一把锁,相当于,一个文件描述符对应一个文件,现在,我们去配钥匙,通过旧的钥匙复制了一把新的钥匙,这样的话,旧的钥匙和新的钥匙都能开启这把锁。对比于dup(),dup2()也一样,通过原来的文件描述符复制出一个新的文件描述符,这样的话,原来的文件描述符和新的文件描述符都指向同一个文件,我们操作这两个文件描述符的任何一个,都能操作它所对应的文件。
所需头文件:
#include<unistd.h>
int dup(int oldfd);
功能:
通过oldfd复制出一个新的文件描述符,新的文件描述符是调用进程文件描述符表中最小可用的文件描述符,最终oldfd和新的文件描述符都指向同一个文件。
参数:
oldfd:需要复制的文件描述符oldfd
返回值:
成功:新文件描述符
失败:-1
dup实例:
下面的例子为,打开一个文件得到文件描述符,并复制该文件描述符,通过这2个描述符分别对此文件进行写
#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<string.h>
int main(int argc,char*argv[])
{
int fd1=0;
int fd2=0;
//打开文件
fd1=open("test.txt",O_CREAT|O_WRONLY,0666);
if(fd1<0){
perror("open");
exit(-1);
}
printf("fd1==============%d\n",fd1);
//通过fd1复制出fd2,最终fd1,fd2都指向test.txt
fd2=dup(fd1);
printf("fd2==============%d\n",fd2);
char*buf1="this is a test for fd1\n";
//操作fd1文件描述符
write(fd1,buf1,strlen(buf1));
char*buf2="this is a test for fd2\n";
//操作fd2文件描述符
write(fd2,buf2,strlen(buf2));
//关闭文件描述符,两个都得关
close(fd1);
close(fd2);
return 0;
}
运行结果:
接下来,我们继续一起学习dup2()的用法,功能和dup()完全一样,但是dup2()复制出来的新文件描述符可以指定任意一个合法的数字
int dup2(int oldfd,int newfd);
功能:
通过oldfd复制出一个新的文件描述符newfd,如果成功,newfd和函数返回值是同一个返回值,最终oldfd和新的文件描述符newfd都指向同一个文件。
参数:
oldfd:需要复制的文件描述符
newfd:新的文件描述符,这个描述符可以人为指定一个合法数字(0-1023),如果指定的数子已经被占用(和某个文件有关联),此函数会自动关闭close()断开这个数字和某个文件的关联,再来使用这个合法数字。
返回值:
成功:返回newfd
失败:返回-1
接着,我们将上面的例子改为用dup2()来实现:
#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
int main(int argc,char*argv[])
{
int fd1;
int fd2;
//打开文件
fd1=open("test.txt",O_CREAT|O_WRONLY,0666);
if(fd1<0){
perror("open");
exit(-1);
}
printf("fd1==============%d\n",fd1);
//通过fd1复制出fd2,最终fd1,fd2都指向“1.txt”
//指定fd2的值为1,1原来指向标准输出设备,先close(),再复制
fd2=dup2(fd1,1);
//下面这句话的内容不会打印到屏幕上,而会写到文件“1.txt”里
//printf()是标准库函数,最终还是会调用系统调用函数write()
//相当于这样,write(1,),往1文件描述符写内容,
//默认的情况下,1文件描述符指向标准输出设备(如,显示屏)
//所以,printf()的内容先显示到屏幕上
//但是现在1文件描述符指向文件“1.txt”
//所以,printf()的内容会写入文件“1.txt”
printf("fd2==============%d\n",fd2);
close(fd1);
close(fd2);
return 0;
}
运行结果: