Linux操作与管理文件(多次打开同一文件,文件共享,fcntl函数,标准IO库)_fopen共享模式打开文件

1.多次打开同一文件

(1)设置fd1,fd2读取文件,经过实验验证,证明了结果是fd1和fd2分别读

(2)设置fd1,fd2写入文件,经过实验验证,证明了结果是fd1和fd2分别写

#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;		// fd 就是file descriptor,文件描述符
	char buf[100] = {0};       //用来存放读取文件内容的buf
	char writebuf[20] = "l love linux";   
	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) || (fd2 == -1))		
	{
		perror("文件打开错误");
		_exit(-1);
	}
	else
	{
		printf("文件打开成功,fd1 = %d. fd2 = %d.\n", fd1, fd2);
	}
	
#if 0  //先关掉写文件
	while (1)
	{
		// 写文件
		ret = write(fd1, "ab", 2);
		if (ret < 0)
		{
			perror("write失败");
			_exit(-1);
		}
		else
		{
			printf("write成功,写入了%d个字符\n", ret);
		}
		ret = write(fd2, "cd", 2);
		if (ret < 0)
		{
			perror("write失败");
			_exit(-1);
		}
		else
		{
			printf("write成功,写入了%d个字符\n", ret);
		}
		sleep(1);
	}	
#endif

#if 1        //先打开读文件
	while(1)
	{
		// 读文件fd1
		memset(buf, 0, sizeof(buf));      //先清空用来存放读取内容的buf
		ret = read(fd1, buf, 2);         
		if (ret < 0)
		{
			printf("read失败\n");
			_exit(-1);
		}
		else
		{	
			printf("fd1:[%s].\n", buf);
		}
		
		sleep(1);
		
		// 读文件fd2
		memset(buf, 0, sizeof(buf));
		ret = read(fd2, buf, 2);
		if (ret < 0)
		{
			printf("read失败\n");
			_exit(-1);
		}
		else
		{	
			printf("fd2:[%s].\n", buf);
		}
		
	}
	
#endif	
	// 第三步:关闭文件
	close(fd1);
	close(fd2);
	
	_exit(0);
}

(3)有时候我们希望接续写而不是分别写?办法就是在open时加O_APPEND标志即可,对文件的读写是原子操作。


2.文件共享的实现方式

(1)文件共享就是同一个文件被多个独立的读写体去同时操作。
(2)常见的有3种文件共享的情况:第一种同一个进程中多次使用open打开同一个文件第二种是在不同进程中去分别使用open打开同一个文件(这时候因为两个fd在不同的进程中,所以两个fd的数字可以相同也可以不同),第三种情况是后面要学的,linux系统提供了dup和dup2两个API来让进程复制文件描述符。

(3)dup和dup2函数

使用dup进行文件描述符复制:会返回一个新的文件描述符

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

#define FILENAME	"1.txt"

int main(void)
{
	int fd1 = -1, fd2 = -1;
	
	fd1 = open(FILENAME, O_RDWR | O_CREAT | O_TRUNC, 0644);
	if (fd1 < 0)
	{
		perror("open");
		return -1;
	}
	printf("fd1 = %d.\n", fd1);
	
	close(1);		// 1就是标准输出stdout
	
	// 复制文件描述符
	fd2 = dup(fd1);		// fd2一定等于1,因为前面刚刚关闭了1,这句话就把
	if (fd2 < 0)        // 1.txt文件和标准输出就绑定起来了,所以以后输出
	{                   // 到标准输出的信息就可以到1.txt中查看了。
		perror("dup");
		return -1;
	}                   
	                   				
	printf("fd2 = %d.\n", fd2);
	printf("this is for test\n");
	
	close(fd1);
	return -1;
}

**dup2复制的文件描述符:**dup2允许用户指定新的文件描述符的数字

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

#define FILENAME	"1.txt"

int main(void)
{
	int fd1 = -1, fd2 = -1;
	
	fd1 = open(FILENAME, O_RDWR | O_CREAT | O_TRUNC, 0644);
	if (fd1 < 0)
	{
		perror("open");
		return -1;
	}
	printf("fd1 = %d.\n", fd1);
	
	
	fd2 = dup2(fd1, 16);
	printf("fd2 = %d.\n", fd2);

	while (1)
	{
		write(fd1, "aa", 2);
		sleep(1);
		write(fd2, "bb", 2);
	}

	close(fd1);
	return -1;
}


3.fcntl函数
(1)fcntl的常用cmd,F_DUPFD这个cmd的作用是复制文件描述符(作用类似于dup和dup2)

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

#define FILENAME	"1.txt"

int main(void)
{
	int fd1 = -1, fd2 = -1;
	
	fd1 = open(FILENAME, O_RDWR | O_CREAT | O_TRUNC, 0644);
	if (fd1 < 0)
	{
		perror("open");
		return -1;
	}
	printf("fd1 = %d.\n", fd1);
**自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。**

**深知大多数嵌入式工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!**

**因此收集整理了一份《2024年嵌入式&物联网开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。**

![img](https://img-blog.csdnimg.cn/img_convert/59de10237363f126b2a461ce4a66a298.png)

![img](https://img-blog.csdnimg.cn/img_convert/69bd97bed0a84687b9c911e0679dc7d4.jpeg)

![img](https://img-blog.csdnimg.cn/img_convert/b51938cfef98c9d8306428f0f0b4b2e2.png)

 **既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上嵌入式&物联网开发知识点,真正体系化!**

![img](https://img-blog.csdnimg.cn/img_convert/198b7d3f2524afacf079949011530f2a.png)

![img](https://img-blog.csdnimg.cn/img_convert/8cdeb3589f8c2e0c783f1d439af41cdd.png)

 

**由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新**

**如果你觉得这些内容对你有帮助,可以+V:Vip1104z获取!!! (备注:嵌入式)**

<img src="https://img-community.csdnimg.cn/images/73bb5de17851459088c6af944156ee24.jpg" alt="img" style="zoom: 67%;" />



# 最后

**资料整理不易,觉得有帮助的朋友可以帮忙点赞分享支持一下小编~**

**你的支持,我的动力;祝各位前程似锦,offer不断,步步高升!!!**

面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新**

**如果你觉得这些内容对你有帮助,可以+V:Vip1104z获取!!! (备注:嵌入式)**

<img src="https://img-community.csdnimg.cn/images/73bb5de17851459088c6af944156ee24.jpg" alt="img" style="zoom: 67%;" />



# 最后

**资料整理不易,觉得有帮助的朋友可以帮忙点赞分享支持一下小编~**

**你的支持,我的动力;祝各位前程似锦,offer不断,步步高升!!!**

**[更多资料点击此处获qu!!](https://bbs.csdn.net/topics/618376385)**
  • 9
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值