5.27 I/O进程

文件描述符拷贝问题

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重定向到标准错误

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值