32_多次打开同一个文件与O_APPEND

时间:2022-06-08 19:51:33

1、一个进程中两次打开同一个文件,分别读取,看看会发生什么

#include<stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>


int main(void)
{
	int fd1 = -1,fd2 = -1;//文件描述符
	char buf1[100] = {0};
	char buf2[100] = {0};
	char writebuf[20] = "i love linux LT.";
	int ret1 = 0,ret2 =0;
	/*打开一个文件*/
	fd1 = open("a.txt",O_RDWR);
	fd2 = open("a.txt",O_RDWR);
	if((-1 == fd1)||(-1 == fd2))
	{
		printf("文件打开错误.\n");	
	}
	else
	{
		printf("文件打开成功.  fd1 = %d.\n",fd1);
		printf("文件打开成功.  fd2 = %d.\n",fd2);
		
	}
	
	/*写文件*/
#if 0
	ret = write(fd, writebuf, strlen(writebuf));
	if(ret < 0)
	{
		printf("写入失败.\n");
	}
	else
	{
		printf("写入的字节数为:%d.\n",ret);	
	}
#endif
	
	//ret = lseek(fd, 0, SEEK_SET);
	
	/*读取文件的内容*/
#if 1 
	memset(buf1, 0 ,sizeof(buf1));
	memset(buf2, 0 ,sizeof(buf2));
	
	ret1 = read(fd1, buf1, 20);
	ret2 = read(fd2, buf2, 20);
	if((-1 == ret1)||(-1 == ret2))
	{
		printf("读取失败.\n");
	}
	else
	{
		printf("f1 :%d.\n", fd1);	
		printf("f1读出的字节数为:%d.\n",ret1);	
		printf("文件内容为:[%s].\n",buf1);

		printf("f2 : %d.\n", fd2);	
		printf("f2读出的字节数为:%d.\n",ret2);	
		printf("文件内容为:[%s].\n",buf2);		
	}
#endif
	
	
	/*关闭一个文件*///关闭一般都不会出什么错误,所以返回值也不去管它了 
	close(fd1);
	close(fd2);
	
	return 0;

}

我们发现读的时候有各自的指针,不会存在两个进程相互影响

关于写入

有的时候需要分别写,有的时候需要接续写,关键看用户的需求,默认情况下是分别写,如果想要接续写入,就在打开时加入O_APPEND 即可

O_APPEND 的内部原理,就是文件指针的移动嘛,分别写两个fd有各自的文件指针,接续写公用一个文件指针。确切的说是移动自己的文件指针的同时,也去移动其他的文件指针,也就是说两个文件指针关联起来了,一个动了,另一个也会跟着动。

O_APPEND 对文件指针的影响,对文件读写是原子的

原子操作,整个操作开始是不会被打断的,必须等结束后才能得以调度。原子就是模块化的进行完才能被打断,交出CPU的使用权。

#include<stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>


int main(void)
{
	int fd1 = -1,fd2 = -1;//文件描述符
	char buf1[100] = {0};
	char buf2[100] = {0};
	char writebuf[20] = "i love linux LT.";
	int ret1 = 0,ret2 =0;
	/*打开一个文件*/
	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))
	{
		printf("文件打开错误.\n");	
	}
	else
	{
		printf("文件打开成功.  fd1 = %d.\n",fd1);
		printf("文件打开成功.  fd2 = %d.\n",fd2);		
	}
	
	/*写文件*/
#if 1
	while(1)
	{
		ret1 = write(fd1, "ab", 2);
		ret2 = write(fd2, "cd", 2);
		sleep(1); //延时1s
		if(ret1 < 0)
		{
			printf("写入失败.\n");
		}
		else
		{
			printf("写入的字节数为:%d.\n",ret1);	
		}	
		
	}
	
#endif
	
	//ret = lseek(fd, 0, SEEK_SET);
	
	/*读取文件的内容*/
#if 0 
	memset(buf1, 0 ,sizeof(buf1));
	memset(buf2, 0 ,sizeof(buf2));
	
	sleep(1); //延时1s
	
	ret1 = read(fd1, buf1, 20);
	ret2 = read(fd2, buf2, 20);
	if((-1 == ret1)||(-1 == ret2))
	{
		printf("读取失败.\n");
	}
	else
	{
		printf("f1 :%d.\n", fd1);	
		printf("f1读出的字节数为:%d.\n",ret1);	
		printf("文件内容为:[%s].\n",buf1);

		printf("f2 : %d.\n", fd2);	
		printf("f2读出的字节数为:%d.\n",ret2);	
		printf("文件内容为:[%s].\n",buf2);		
	}
#endif
	
	
	/*关闭一个文件*///关闭一般都不会出什么错误,所以返回值也不去管它了 
	close(fd1);
	close(fd2);
	
	return 0;

}