Linux系统中利用open函数多次打开同一个文件操作方法

news2024/11/13 12:42:07

     大家好。

     今天的话主要和大家聊一聊,在Linux系统中如果一个文件被打开多次会出现什么情况。     

目录

第一:多次打开同一个文件

​第二:一个文件被打开多次,在内存中不会存在多份动态文件

​第三:多次open打开同一个文件,不同文件描述符对应的读写位置偏移量是相互独立的​


 

第一:多次打开同一个文件

    大家看到这个标题可能会有疑问,同一个文件还能被多次打开?事实确实如此,同一个文件可以被 多次打开,譬如在一个进程中多次打开同一个文件、在多个不同的进程中打开同一个文件,那么这些操作都 是被允许的。本小节就来探讨下多次打开同一个文件会有一些什么现象以及相应的细节问题?

     当一个进程内多次open打开同一个文件,那么会得到多个不同的文件描述符fd,同理在关闭文件的时候也需要调用close依次关闭文件描述符。

#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#include <unistd.h>#include <stdio.h>#include <stdlib.h>int main(void){ int fd1, fd2, fd3; int ret; /* 第一次打开文件 */ fd1 = open("./test_file", O_RDWR); if (-1 == fd1) { perror("open error"); exit(-1); } /* 第二次打开文件 */ fd2 = open("./test_file", O_RDWR); if (-1 == fd2) { perror("open error"); ret = -1; goto err1;  } /* 第三次打开文件 */ fd3 = open("./test_file", O_RDWR); if (-1 == fd3) { perror("open error"); ret = -1; goto err2; } /* 打印出 3 个文件描述符 */ printf("%d %d %d\n", fd1, fd2, fd3); close(fd3); ret = 0;err2: close(fd2);err1: /* 关闭文件 */ close(fd1); exit(ret);}

    在上述代码中,通过3次调用open函数对test_file文件打开了3次,最后将3次得到的文件描述符打印出来,在当前目录下存在test_file文件,接下来编译测试​:

    从打印结果可知,三次调用 open 函数得到的文件描述符分别为 6、7、8,通过任何一个文件描述符对文件进行 IO 操作都是可以的,但是需要注意是,调用 open 函数打开文件使用的是什么权限,则返回的文件描述符就拥有什么权限,文件 IO 操作完成之后,在结束进程之前需要使用 close 关闭各个文件描述符。

​第二:一个文件被打开多次,在内存中不会存在多份动态文件

     如果同一个文件被多次打开,那么该文件所对应的动态文件是否在内存中也存在多份?也就是说,多次打开同一个文件是否会将其文件数据多次拷贝到内存中进行维护?

#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#include <unistd.h>#include <stdio.h>#include <stdlib.h>#include <string.h>int main(void){ char buffer[4]; int fd1, fd2; int ret; /* 创建新文件 test_file 并打开 */ fd1 = open("./test_file", O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); if (-1 == fd1) { perror("open error"); exit(-1); } /* 再次打开 test_file 文件 */ fd2 = open("./test_file", O_RDWR); if (-1 == fd2) { perror("open error"); ret = -1; goto err1; } /* 通过 fd1 文件描述符写入 4 个字节数据 */ buffer[0] = 0x11; buffer[1] = 0x22; buffer[2] = 0x33; buffer[3] = 0x44; ret = write(fd1, buffer, 4); if (-1 == ret) { perror("write error"); goto err2; } /* 将读写位置偏移量移动到文件头 */ ret = lseek(fd2, 0, SEEK_SET); if (-1 == ret) { perror("lseek error"); goto err2; } /* 读取数据 */ memset(buffer, 0x00, sizeof(buffer)); ret = read(fd2, buffer, 4); if (-1 == ret) { perror("read error"); goto err2; } printf("0x%x 0x%x 0x%x 0x%x\n", buffer[0], buffer[1], buffer[2], buffer[3]); ret = 0;err2: close(fd2);err1: /* 关闭文件 */ close(fd1); exit(ret);}

     当前目录下不存在test_file文件,代码中,第一次调用open函数新建并打开test_file文件,第二次调用open函数再次打开它,新建文件时,文件大小为0;首先通过文件描述符 fd1 写入4 个字节数据(0x11/0x22/0x33/0x44),从文件头开始写;然后再通过文件描述符 fd2 读取 4 个字节数据,也是从文件头开始读取。假如,内存中只有一份动态文件,那么读取得到的数据应该就是 0x11、0x22、0x33、0x44,如果存在多份动态文件,那么通过 fd2 读取的是与它对应的动态文件中的数据,那就不是 0x11、0x22、0x33、0x44,而是读取出 0 个字节数据,因为它的文件大小是 0。

    根据以上打印结果,打印显示出来的数据是0x11/0x22/0x33/0x44,所以由此可知,即使多次打开同一个文件,内存中也只有一份动态文件。

​第三:多次open打开同一个文件,不同文件描述符对应的读写位置偏移量是相互独立的​

    同一个文件件被多次打开,会得到多个不同的文件描述符,也就意味着会有多个不同的文件表,而文件读写偏移量信息就记录在文件表数据结构中,所以从这里可以推测不同的文件描述符所对应的读写偏移量是相互独立的,并没有关联在一起,并且文件表中 i-node 指针指向的都是同一个 inode,如下图所示:

​总结:多次打开同一个文件,返回的文件描述符各不相同,但是操作的仍然是同一个文件​。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2085.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

第一章 - Windows安装VMware Workstation Pro

文章目录前言一、VMware Workstation Pro安装的前提条件二、VMware Workstation Pro下载三、VMware Workstation Pro安装前言 Linux是一个开源、免费的操作系统&#xff0c;其稳定性、安全性、处理多并发已经得到业界认可&#xff0c;目前很多企业级的项目都会部署到Linux系统…

结构体内存对齐

在知道了结构体类型的基本使用之后&#xff0c;我们需要深入探讨一个问题&#xff0c;即计算结构体的大小&#xff0c;这也是一个热门的考点&#xff1a;结构体内存对齐。 目录 一、结构体的对齐规则 二、例题 2.1 例题一 2.2 例题二 2.3 例题三 ​编辑 三、为什么存在内存…

【C++】vector,list迭代器失效

1.vector迭代器失效 vector容器的物理基础是线性表&#xff0c;底层是指针变量实现的。 在这里导致vector迭代器失效的原因会有两种-----插入失效&#xff0c;删除失效。 1.2插入数值导致迭代器失效 1.21扩容导致迭代器失效 我们在一块vector空间插入pos&#xff08;20&…

第三章 单向链表的讲解与实现

初阶数据结构 第一章 时间复杂度和空间复杂度 第二章 动态顺序表的实现 第三章 单向链表的讲解与实现 文章目录初阶数据结构前言一、什么是链表&#xff1f;二、节点的定义&#xff1a;三、单向链表接口函数1、打印&#xff1a;2、尾插&#xff1a;3、头插&#xff1a;4、尾删…

改进YOLOv7系列: 最新结合用于小目标的新CNN卷积构建块

&#x1f4a1;统一使用 YOLOv7 代码框架&#xff0c;结合不同模块来构建不同的YOLO目标检测模型。&#x1f31f;本项目包含大量的改进方式,降低改进难度,改进点包含【Backbone特征主干】、【Neck特征融合】、【Head检测头】、【注意力机制】、【IoU损失函数】、【NMS】、【Loss…

Linux-进程控制

进程控制进程创建fork函数写时拷贝fork常规用法fork调用失败的原因进程终止进程等待进程程序替换程序替换的原理如何程序替换进程创建 fork函数 fork之前父进程独立运行&#xff0c;fork之后&#xff0c;父子两个执行流分别执行。 进程具有独立性&#xff0c;代码和数据必须独立…

机器学习HMM模型

目录1 马尔科夫链1.1 简介1.2 经典举例1.3 小结2 HMM简介2.1 简单案例2.2 案例进阶2.2.1 问题阐述2.2.2 问题解决3 HMM模型基础3.1 什么样的问题需要HMM模型3.2 HMM模型的定义3.3 一个HMM模型实例3.4 HMM观测序列的生成3.5 HMM模型的三个基本问题4 前向后向算法评估观察序列概率…

计算机毕业设计-SSM高校社团招新系统-JavaWeb大学生社团管理系统-源码+文档+讲解

注意&#xff1a;该项目只展示部分功能&#xff0c;如需了解&#xff0c;评论区咨询即可。 本文目录1.开发环境2.系统的设计背景3 前后台功能设计3.1 前台功能3.2 后台功能4 系统页面展示4.1 学生功能模块展示4.2 干部功能模块展示4.3 管理员功能模块展示5 更多推荐6 部分功能代…

如何用IDEA提高你的开发效率

前言 ​ 作为一名java开发工程师&#xff0c;IDEA无疑是我日常接触最多的工具。因此&#xff0c;能否高效使用IDEA软件&#xff0c;一定程度上决定了我们的开发效率。本文将主要介绍IDEA中的四个便于提高开发效率的功能&#xff0c;常用快捷键、实时模版、后缀补全、文件和代码…

《本地计算机DNS缓存文件》

C:\Windows\System32\drivers\etc 36.152.44.95 www.baidu.com 正常访问www.baidu.com可以DNS抓包&#xff0c;将百度的IP及域名加入文件位置的hosts文件中即该IP和域名将不再请求网络上的DNS服务器&#xff0c;即加快域名解析&#xff1b; 具体作用&#xff1a; 1.加快域名解…

什么是RPC框架?

什么是RPC&#xff1f; In distributed computing, a remote procedure call (RPC) is when a computer program causes a procedure (subroutine) to execute in a different address space (commonly on another computer on a shared network), which is coded as if it wer…

创新能力 | 产品经理实践中常犯的七大错误

做产品是一个既感性又理性的过程&#xff0c;纵然有很多前辈同行的经验传承和技巧指导&#xff0c;但在落到实处是时&#xff0c;总难免犯一些错误。有些是经验不足导致&#xff0c;有些则是产品经理对于人性的浅见寡闻。本文作为产品经理实践指南专题的中级篇&#xff0c;阐述…

用 AWTK 和 AWPLC 快速开发嵌入式应用程序 (2)-走马灯

AWPLC 目前还处于开发阶段的早期&#xff0c;写这个系列文章的目的&#xff0c;除了用来验证目前所做的工作外&#xff0c;还希望得到大家的指点和反馈。如果您有任何疑问和建议&#xff0c;请在评论区留言。 1. 背景 AWTK 全称 Toolkit AnyWhere&#xff0c;是 ZLG 开发的开源…

全球名校AI课程库(35)| 辛辛那提大学 · 微积分Ⅱ课程『MATH101 Calculus II』

&#x1f3c6; 课程学习中心 | &#x1f6a7; CS数学基础课程合辑 | &#x1f30d; 课程主页 | &#x1f4fa; 中英字幕视频 | &#x1f680; 项目代码解析 课程介绍 Trefor Bazett 教授在 Cincinnati 大学任教时&#xff0c;制作了两套完整的的数学课程&#xff08;微积分、离…

Eclipse创建Servlet项目-7

目录 1、创建动态 Web 项目 2、使用 Eclipse 创建 Servlet 3、配置 web.xml 4、部署项目并启动服务器 通过前面的学习&#xff0c;我们了解了如何在 Tomcat 目录下手动部署 Servlet&#xff0c;这种方式不但效率低下&#xff0c;而且容易出错。因此&#xff0c;在实际开发中…

变量常量,基本数据类型及数据类型转换

⭐️ 变量常量与基本数据类型及数据类型转换 &#x1f4cd; 来自&#xff1a;中南林业科技大学软件协会学术部&#xff1a;谢添 ⏲ 时间&#xff1a;2022 - 10 - 29 至 2022 - 10 - 30 &#x1f3e0; 官网&#xff1a;https://www.csuftsap.cn/ ✏️ 本章所有提供代码均已测…

四旋翼无人机学习第4节--STM32、MPU9250等器件的绘制

0 前言 当画stm32、mpu9250这种多引脚的芯片&#xff0c;就需要参考芯片手册啦。 这里给大家推荐一个芯片手册查询网站。 半导小芯-芯片查询工具 进入网站&#xff0c;输入芯片的具体名称&#xff0c;点击查询即可。 最后点击下载即可。 1 stm32芯片手册引脚查询 选择引脚…

学习在Git项目中使用子模块(图文教程)

一般认为 父项目 是当前正在做的主要工作&#xff0c;但需要依赖 子模块 中提供的算法或者工具。父项目 与 子模块 不是同一批人维护的&#xff0c;或者是需要分开维护的。 此情此景&#xff0c;需要学习该教程了&#xff01;&#xff01;&#xff01; 文章目录1 如何在父项目…

基于Java的一个可自由拖拽的BI可视化系统(附源码)

介绍 这是一个可自由拖拽的BI可视化系统支持主流的关系数据&#xff1a;MySQL&#xff0c;Oracle&#xff0c;PostgreSQL等同时支持Apache Doris&#xff0c;这个一开始初衷就是为了 Doris 数据可视化分析做的后端框架使用了若依 功能 按项目管理数据看板看板具备分享功能可以…

每天五分钟机器学习:超平面分离定理和凸优化

凸集和凸函数 在点集拓扑学与欧几里得空间中,凸集是一个点集,其中每两点之间的直线上的点都落在该点集中。如下所示: 函数任意两点(x,f(x))和(y,f(y))连线上的值大于(x,y)区间内任意一点m的值f(m),那么这个函数就是一个凸函数: 超平面分离定理 空间中存在两类样本,…