Linux多次打开同一个文件与O_APPEND

重复打开同一文件读取
  1. 一个进程中两次打开同一个文件读取,然后分别读取,观察结果。
  2. 猜测结果有两种情况:
    • fd1和fd2分别读。
    • 接续读。
  3. 经过实验验证,结果是分别读。说明:fd1和fd2所对应的文件指针式不同的2个独立的指针。文件指针是包含在动态文件的文件管理表中的,所以可以看出Linux系统的进程中不同fd对应的是不同的独立的文件管理表。
  • 附源码:
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>

int main(int argc,char *argv[])
{
	int fd1 = -1,fd2 = -1;	
	char buf[100]={0};
	char w_buf[20]="l love linux\n";
	int ret = -1;
	
	//第一步:打开文件
	fd1 = open("a.txt",O_RDWR);
	fd2 = open("a.txt",O_RDWR);
	if ((-1 == fd1)||(-1 == fd2))//有时候也写成fd < 0
	{
		//printf("文件打开错误\n");
		perror("open");
		return -1;
	}
	else
	{
		printf("文件打开成功,fd1 = %d ,fd2 = %d \n",fd1,fd2);
	}
	
#if 1
	while(1)
	{
		//fd1读文件
		memset(buf,0,sizeof(buf));
		ret = read(fd1,buf,2);
		if(-1 == ret)
		{
			printf("读取失败\n");
		}
		else
		{
			//printf("实际读取了%d字节\n",ret);
			printf("fd1:[%s]\n",buf);
			
		}
		
		sleep(1);
		
		//fd2读文件
		memset(buf,0,sizeof(buf));
		ret = read(fd2,buf,2);
		if(-1 == ret)
		{
			printf("读取失败\n");
		}
		else
		{
			//printf("实际读取了%d字节\n",ret);
			printf("fd2:[%s]\n",buf);
			
		}
	}
	
#endif
	


	//第三步:关闭文件
	close(fd1);
	close(fd2);
	
	
	return 0;
}
重复打开统一文件写入
  1. 一个进程中打开同一个文件,fd1、fd2都写入,观察结果。
  2. 我们有时候需要分别写入,优势需要接续写,所以两种没有好坏之分。
  3. 实验验证,结果为分别写入。即fd2会覆盖fd1写入的值。
  • 源码:
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>

int main(int argc,char *argv[])
{
	int fd1 = -1,fd2 = -1;	
	char buf[100]={0};
	char w_buf[20]="l love linux\n";
	int ret = -1;
	
	//第一步:打开文件
	fd1 = open("a.txt",O_RDWR | O_TRUNC | O_CREAT,0666);
	fd2 = open("a.txt",O_RDWR | O_TRUNC | O_CREAT,0666);
	if ((-1 == fd1)||(-1 == fd2))//有时候也写成fd < 0
	{
		//printf("文件打开错误\n");
		perror("open");
		return -1;
	}
	else
	{
		printf("文件打开成功,fd1 = %d ,fd2 = %d \n",fd1,fd2);
	}
	
	//第二步:读写文件
#if 1
	while(1)
	{
		//fd1写文件
		ret = write(fd1,"ab",2);
		if(ret<0)
		{
			perror("fd1 write error\n");
			_exit(-1);
		}
		else
		{
			printf("写成功,写入了%d个字符\n",ret);
		}
		sleep(1);
		//fd2写文件
		ret = write(fd2,"cd",2);
		if(ret<0)
		{
			perror("fd2 write error\n");
			_exit(-1);
		}
		else
		{
			printf("写成功,写入了%d个字符\n",ret);
		}
	}
#endif

	//第三步:关闭文件
	close(fd1);
	close(fd2);
	
	return 0;
}
加O_APPEND解决覆盖问题
  • 有时候我们希望接续写而不是分别写,在open是加O_APPEND标志即可。
  • 源码:
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>

int main(int argc,char *argv[])
{
	int fd1 = -1,fd2 = -1;	
	char buf[100]={0};
	char w_buf[20]="l love linux\n";
	int ret = -1;
	
	//第一步:打开文件
	fd1 = open("a.txt",O_RDWR | O_TRUNC | O_CREAT | O_APPEND,0666);
	fd2 = open("a.txt",O_RDWR | O_TRUNC | O_CREAT | O_APPEND,0666);
	if ((-1 == fd1)||(-1 == fd2))//有时候也写成fd < 0
	{
		//printf("文件打开错误\n");
		perror("open");
		return -1;
	}
	else
	{
		printf("文件打开成功,fd1 = %d ,fd2 = %d \n",fd1,fd2);
	}
	
	//第二步:读写文件
#if 1
	while(1)
	{
		//fd1写文件
		ret = write(fd1,"ab",2);
		if(ret<0)
		{
			perror("fd1 write error\n");
			_exit(-1);
		}
		else
		{
			printf("写成功,写入了%d个字符\n",ret);
		}
		sleep(1);
		//fd2写文件
		ret = write(fd2,"cd",2);
		if(ret<0)
		{
			perror("fd2 write error\n");
			_exit(-1);
		}
		else
		{
			printf("写成功,写入了%d个字符\n",ret);
		}
	}
#endif

	//第三步:关闭文件
	close(fd1);
	close(fd2);
	
	return 0;
}
O_APPEND的实现原理和其原子操作说明
  1. O_APPEND能够将分别写改为接续写的关键核心是文件指针。分别写的原理就是2个fd拥有不同的文件指针并且只 考虑自己的位移。但是O_APPEND标志可以让write和read函数内部移动自己文件的同时也去把别人的文件指针同时移动。fd1和fd2还是各自用于一个独立的文件指针,但是这两个文件指针关联起来了,一个动了另一个也会动。
  2. O_APPEND对文件指针的影响,对文件的读写时原子的。
  3. 原子操作的含义是:整个操作一旦开始是不会被打断的,必须直到操作结束其他代码才能得以调度运行,这就叫原子操作。每种操作系统中都有一些机制来实现原子操作,以保证那些需要原子操作的任务可以运行。
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值