文件描述符拷贝问题
1.文件描述符拷贝之dup函数与直接拷贝
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<unistd.h>
#include<errno.h>
int main(int argc, const char *argv[])
{
int fd1,fd2,fd3;
//以只读的形式打开文件
if((fd1 = open("./Text.txt", O_RDONLY)) == -1)
{
perror("open file");
return -1;
}
//读取数据
char buf1[10];
int ret = read(3, buf1, sizeof(buf1)); //从文件中读取数据
write(1, buf1, ret); //将数据打印在终端上
//文件描述符的直接拷贝
fd3=fd1;
char buf3[10];
ret = read(fd3, buf3, sizeof(buf3)); //从文件中读取数据
write(1, buf3, ret); //将数据打印在终端上
//使用dup函数拷贝一个文件描述符
fd2 = dup(fd1);
printf("fd1 = %d, fd2 = %d,fd3=%d\n", fd1, fd2,fd3);
//通过fd2读取数据
char buf2[10];
ret = read(4, buf2, sizeof(buf2));
write(1, buf2, ret);
//关闭文件
if(close(fd1))
{
perror("close fd1");
}
printf("关闭文件描述符 fd1\n");
ret = read(fd3, buf3, sizeof(buf3)); //从文件中读取数据
write(1, buf3, ret); //将数据打印在终端上
ret = read(fd2, buf2, sizeof(buf2));
write(1, buf2, ret);
if(close(fd2))
{
perror("close fd2");
}
printf("关闭文件描述符 fd2\n");
ret = read(fd2, buf2, sizeof(buf2));
write(1, buf2, ret);
return 0;
}
运行结果
结论:直接拷贝文件描述符,描述符值不变,eg :fd1=3,fd3=3;
dup拷贝文件描述符,描述符值改变,eg :fd1=3,fd2=4;
但是这两种拷贝所得的描述符指向的都还是原来的光标,即,fd1,fd2,fd3指向的是同一个光标。
2.通过open多次打开同一文件
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<unistd.h>
#include<errno.h>
int main(int argc, const char *argv[])
{
int fd1,fd2,fd3;
//三个文件描述符打开同一个文件
if((fd1=open("./Text.txt",O_RDONLY))==-1)
{
perror("open 1file");
return -1;
}
if((fd2=open("./Text.txt",O_RDONLY))==-1)
{
perror("open 2file");
return -1;
}
if((fd3=open("./Text.txt",O_RDONLY))==-1)
{
perror("open 2file");
return -1;
}
printf("fd1=%d\nfd2=%d\nfd3=%d\n",fd1,fd2,fd3);
char str1[9];
char str2[8];
char str3[7];
int ret;
//通过描述符fd1输出
ret=read(fd1,str1,sizeof(str1)-1);
write(1,str1,sizeof(str1)-1);
putchar(10);
//关闭描述符fd1
close(fd1);
//通过描述符fd2输出
read(fd2,str2,sizeof(str2)-1);
printf("str2=%s\n",str2);
//再次通过描述符fd2输出
ret=read(fd2,str2,sizeof(str2)-1);
write(1,str2,sizeof(str2)-3);
puts("");
//通过描述符fd3输出
read(fd3,str3,sizeof(str3)-1);
printf("str3=%s\n",str3);
close(fd2);
close(fd3);
return 0;
}
运行结果
结果分析:使用open多次打开同一文件,文件的描述符不同,且各自相互独立,对应的光标也不同。例如,fd2的光标已经移动第二行的789后面,但是fd3的光标仍然从文件开头开始。
3.文件描述符拷贝函数之dup2函数
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<unistd.h>
#include<errno.h>
int main(int argc, const char *argv[])
{
int fd1,fd2;
if((fd1=open("./Text.txt",O_RDONLY))==-1)
{
perror("open file");
return -1;
}
char buf[10];
int ret;
ret=read(fd1,buf,sizeof(buf)-1);
write(1,buf,sizeof(buf)-1);
puts("");
printf("fd1=%d\n",fd1);
//通过dup2让fd2指向与fd1相同的文件,并赋予fd2文件描述符,并不按照最小位原则
fd2=dup2(fd1,6);
printf("fd2=%d\n",fd2);
//close(fd1);
char buf2[10];
ret=read(fd2,buf2,sizeof(buf2)-1);
write(1,buf2,sizeof(buf2)-1);
puts("");
//close(fd2);
ret=read(fd1,buf,sizeof(buf)-1);
write(1,buf,sizeof(buf)-1);
puts("");
close(fd1);
close(fd2);
return 0;
}
运行结果
结论,新描述符接力旧描述符,并且新描述符并不按照最小位设置,自己定义。
补充
dup2(fd, STDIN_FILENO); // 将fd重定向到标准输入
dup2(fd, STDOUT_FILENO); // 将fd重定向到标准输出
dup2(fd, STDERR_FILENO); // 将fd重定向到标准错误