Linux--基础IO(上)

目录

1. 文件的边角知识

1.1 文件是什么?

1.2 文件是怎么打开的?

1.3 进程与文件

进程与文件的关系 

2. 重温c语言文件接口

2.1 打开文件的方式 

2.2 读写文件接口的重温 

2.2.1 写文件 

2.2.2 读文件 

3. 系统文件I/O

3.1 系统接口 

3.2 系统接口的参数详解 

3.3 文件描述符 

3.4 fd的分配规则 

3.5 重定向 

 3.6 dup2


1. 文件的边角知识

1.1 文件是什么?

文件=内容+属性。常说的对文件进行操作,不仅是对文件内容的读写,也有对文件属性的修改。比如修改文件名称,更新文件最新写入时间等。

1.2 文件是怎么打开的?

在linux的命令行界面中,我们打开文件是通过指令打开;在图形化界面中,我们只需要点击文件就可以打开。指令本质是程序,图形化界面点击同样也是一种程序,只不过被封装成了点击的行为罢了,在底层其实没有区别。

访问文件之前需要先打开文件,从上面的叙述中我们明白,文件就是被程序打开的,也即文件的打开工作是进程做的。

为什么呢?为什么不直接让操作系统打开?

文件不能直接被操作系统打开,而是由应用程序通过系统调用来请求操作系统打开文件。  

冯诺依曼体系结构中明确规定,cpu不能与硬件接触。而对文件的处理要靠cpu来运算,但文件存储在磁盘中,因此我们需要将文件加载到内存中才能进行操作,当对文件的修改完成后,将新的文件在磁盘中更新。 

1.3 进程与文件

文件是被进程打开的,但进程能够打开的文件并不只限于一个,即进程与文件是一对多的关系。 

已打开的文件被加载到内存中,那么没有打开的文件呢?在磁盘里。

进程与文件的关系 

我们知道,进程打开后会有一个进程控制块pcb来管理进程。Linux中的pcb被称为task_struct,即管理进程的结构体。文件当然也需要类似的结构体来管理,内核中必然有一个描述被打开文件的结构体,并用其定义对象,我们姑且称他为file_struct。

当进程打开文件后,进程与文件的关系就如下图。

在Linux内核源码中,我们看到在task_struct中包含files_struct结构体,注释为打开文件的信息。 

2. 重温c语言文件接口

2.1 打开文件的方式 

有没有发现一件奇妙的事情,w与输出重定向>功能十分类似,而a则与追加重定向>>类似,r与输入重定向<类似。

2.2 读写文件接口的重温 

2.2.1 写文件 

2.2.2 读文件 

c语言会默认打开三个输入输出流:stdin,stdout,stderr。

我们可以将stdin视作键盘,将stdout视作显示器,stderr视作显示器(输出错误信息)。

我们来看看:

3. 系统文件I/O

3.1 系统接口 

 我们前面说,文件只能被程序通过系统调用来打开,也就是说c语言的文件接口中必定封装着文件操作的诸多系统调用。

我们之前说,c语言会默认打开三个流。注意:这里的FILE*是c语言自己封装的结构体。我们来看看他们是如何封装文件的系统调用 。

下图是我们常用的几个系统调用接口。我们发现,open会返回一个int值fd,其他的接口都会使用这个fd。有没有可能,这个fd就类似于进程的pid,是文件的标识符呢?答案是肯定的。

也就是说,FILE*中封装着文件的标识符fd。

验证:

因此我们可以在系统调用中使用0/1/2来使用键盘/显示器/显示器。 

3.2 系统接口的参数详解 

我们以open接口为例:

下图介绍了flag与mode的常用选项。 

这里的flag传参涉及了位运算传参 ,我们写一段代码来看看。

#include<stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include<unistd.h>
#include<string.h>
int main()
{size_t fd = open("./log.txt",O_WRONLY|O_CREAT|O_TRUNC,0666);//以只写权限打开,如果文件不存在就创建,存在就清空const char* str="hahaha dashagua!";write(fd,str,strlen(str));close(fd);return 0;
}

3.3 文件描述符 

 文件描述符即3.1 中的fd,那么files_struct是如何管理被打开的文件呢?

请看下图,下面的structural flie* fd array[]就是一个指针数组,里面存放着每一个文件结构体的地址,而文件描述符就是数组下标,进程通过文件下标访问文件。

3.4 fd的分配规则 

当我们关闭fd为1的stdout时,此时再打开一个文件log.txt,我们会发现此时我们对1的写入,会写进 log.txt中。这是因为此时打开的文件其fd为1。

如果我们关闭0或2,输出就会是0/2。

文件描述符的分配规则:在files_struct数组当中,找到当前没有被使用的最小的一个下标,作为新的文件描述符。
 

3.5 重定向 

 

我们发现,本来应该输出到显示器上的内容,输出到了文件 myfile 当中,其中,fd=1。这种现象叫做输出
重定向。常见的重定向有:>, >>, <
那重定向的本质是什么呢?

重定向的本质就是改变了文件的输入输出流。
 

针对这一现象,我们有一个系统接口dup2,可以实现重定向的功能。

 3.6 dup2

 接口解释:

代码实验: 

#include<stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include<unistd.h>
#include<string.h>int main()
{size_t fd = open("./log.txt",O_WRONLY|O_CREAT|O_TRUNC,0666);if(fd<0){perror("open error!");return 1;}dup2(fd,1);//重定向,让fd覆盖fd为1的显示器write(fd,"hahahah\n",8);//向fd写入,验证并非替换,且fd并未被关闭printf("我原本是要输入到显示器的,你看看我现在在哪?\n");//此时fd,1都指向log.txtclose(fd);printf("fd关了,你看看我现在在哪?\n");//printf("hello hello!\n");return 0;
}

结果展示: 

原理剖析图:

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

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

相关文章

【深度学习-第5篇】使用Python快速实现CNN分类(模式识别)任务,含一维、二维、三维数据演示案例(使用pytorch框架)

在之前的文章中介绍了CNN的图解入门&#xff0c;CNN的MATLAB分类实现&#xff0c;CNN的MATLAB回归实现。 卷积神经网络(Convolutional Neural Networ&#xff0c;简称CNN)是一种广泛应用于图像识别领域的深度学习算法。它通过模拟人类视觉系统的层次结构&#xff0c;可以自动提…

nginx-1.24.0 安装教程

下载nginx安装包 mkdir -p /home/app cd /home/app wget http://nginx.org/download/nginx-1.24.0.tar.gz 解压缩 tar -zxf nginx-1.24.0.tar.gz 下载nginx二进制包编译所需的工具和依赖 yum install gcc-c pcre pcre-devel zlib zlib-devel openssl openssl-devel -y 编译…

Arduino平衡小车

一&#xff0c;TB6612FNG电机驱动芯片 TB6612FNG是东芝半导体公司生产的一款直流电机驱动器件&#xff0c;它具有大电流MOSFET-H桥结构&#xff0c;双通道电路输出&#xff0c;可同时驱动2个电机. 参数名称参数值电压范围2.7-5.5V最大输入电压15V输出电流1.2A(平均)/3.2A&…

Vitis HLS 学习笔记--HLS入门示例集合-目录

目录 1. 示例集合概述 2. Interface 接口 2.1 Aggregation_Disaggregation 聚合与解聚 2.1.1 aggregation_of_m_axi_ports 2.1.2 aggregation_of_nested_structs 2.1.3 aggregation_of_struct 2.1.4 auto_disaggregation_of_struct 2.1.5 disaggregation_of_axis_port …

模块化 手写实现webpack

模块化 common.js 的导入导出方法&#xff1a; require \ export 和 module.exports export 和 module.export nodejs 内存1.4G -> 2.8G cjs ESModule 主要区别&#xff1a; require属于动态类型&#xff1a;加载执行 同步 esmodul是静态类型&#xff1a;引入时并不会真的去…

Autosar AP的基本构成

1. 引言 Autosar AP的体系结构是怎样的呢&#xff1f;从整体的宏观的方向上划分&#xff0c;分为 1&#xff09;应用层&#xff0c;其中放置各种应用组件SWCs。2&#xff09;运行时基本功能软件族群&#xff0c;提供基本AutoSar基本软件中间件&#xff0c;比如经典的通信服务…

【漏洞复现】云时空社会化商业ERP系统slogin SQL注入漏洞

漏洞描述&#xff1a; 云时空社会化商业ERP系统slogin存在SQL注入漏洞&#xff0c;攻击者可以通过此漏洞获取数据库敏感信息。 搜索语法: Fofa-Query: app"云时空社会化商业ERP系统" 漏洞详情&#xff1a; 1.云时空社会化商业ERP系统。 2.漏洞POC&#xff1a; …

智慧园区引领未来产业趋势:科技创新驱动园区发展,构建智慧化产业新体系

目录 一、引言 二、智慧园区引领未来产业趋势 1、产业集聚与协同发展 2、智能化生产与服务 3、绿色可持续发展 三、科技创新驱动园区发展 1、创新资源的集聚与整合 2、创新成果的转化与应用 3、创新文化的培育与弘扬 四、构建智慧化产业新体系 1、优化产业布局与结构…

JavaScript:将input标签中的内容打印到控制台

使用浏览器进行开发时&#xff0c;按F12可以查看网页信息。 目标&#xff1a;实现将input标签中的内容&#xff0c;打印到控制台&#xff08;console&#xff09; HTML页面的关键代码实现&#xff1a; 登录功能&#xff1a; HTML代码&#xff1a; <div class"form-…

Node.js 22 发布,原生支持 WebSocket 客户端

昨日&#xff0c;Node.js 官方博客正式宣布 Node.js 22 的发布&#xff01;新版本亮点包括 require() ES 模块、WebSocket 客户端、V8 JavaScript 引擎的更新等&#xff01; Node.js 22 将在 10 月进入长期支持 (LTS)&#xff0c;但在此之前&#xff0c;它将是接下来六个月的 …

【AI相关】数学和统计学知识

数学和统计学的知识可以分为两部分&#xff1a; 一部分是线性代数中的基础概念&#xff0c;比如标量、向量和张量。 另一部分是概率统计中常见的分布类型&#xff0c;比如正态分布和伯努利分布。 线性代数 什么是标量&#xff1f; 标量是一个单独的数&#xff0c;可以是整…

2021年全国大学生电子设计竞赛D题——基于互联网的摄像测量系统(二)

09 电路设计 前面介绍了系统的硬件框图如下&#xff1a; 硬件基本分为三块&#xff0c;两个摄像节点&#xff0c;一个终端节点。 1. 摄像节点硬件 摄像节点由一个DE10-Nano开发板和一个D8M摄像头实现&#xff0c;DE10-Nano开发板的HDMI接口外接HDMI显示器来显示拍摄到的视频。…

vue3的getCurrentInstance获取当前组件实例

vue3的setup中没有this时需要使用getCurrentInstance()来获取。 在 Vue 3 中&#xff0c;getCurrentInstance 方法可以在组合式 API&#xff08;Composition API&#xff09;中获取当前组件实例。这个方法返回一个包含了组件实例的对象&#xff0c;你可以用它来访问组件的 pro…

详解MySQL C API 相关接口(大白话就是:MySQL的c语言怎么写)

文章目录 1、C API 官方文档2、初始化 MYSQL3、连接 MySQL设置连接字符集&#xff08;使得客户端编码方式匹配&#xff09; 4、下发 mysql 指令5、获取 mysql 查询结果(保存起来)获取行与列遍历存储结果 6、释放 MYSQL\_RES 对象7、关闭 MySQL 连接8、总结 1、C API 官方文档 …

动态规划---斐波那契数列模型

目录 一、斐波那契数列的基本概念 二、动态规划在斐波那契数列中的应用与优势 三、实际案例&#xff1a;使用动态规划解决斐波那契数列问题 四、动态规划问题的做题步骤 五、例题 1、第N个泰波那契数---点击跳转题目 2、三步问题----点击跳转题目 3、最小花费爬楼梯---…

FANUC机器人socket通讯硬件配置

一、添加机器人选配包 Fanuc机器人要进行socket通讯&#xff0c;需要有机器人通讯的选配包&#xff0c;1A05B-2600-R648 User Socket Msg&#xff0c;1A05B-2600-R632 KAREL&#xff0c;1A05B-2600-R566 KAREL Diagnostic&#xff0c;1A05B-2600-J971 KAREL Use Sprt FCTN。 二…

【漏洞复现】WebLogic XMLDecoder反序列化(CVE-2017-10271)

1、漏洞描述 CVE-2017-10271漏洞产生的原因大致是Weblogic的WLS Security组件对外提供webservice服务&#xff0c;其中使用了XMLDecoder来解析用户传入的XML数据&#xff0c;在解析的过程中出现反序列化漏洞&#xff0c;导致可执行任意命令。攻击者发送精心构造的xml数据甚至能…

clickhouse数据去重函数介绍(count distinct)

非精确去重函数&#xff1a;uniq、uniqHLL12、uniqCombined 精确去重函数&#xff1a;uniqExact、groupBitmap 测试数据量&#xff1a;2000w 结论&#xff1a; 1.整形值精确去重场景&#xff0c;groupBitmap 比 uniqExact至少快 2x 2.groupBitmap仅支持无符号整形值去重&#x…

文化旅游3D数字孪生可视化管理平台推动文旅产业迈向更加美好的未来

随着数字化、智能化管理成为文旅产业发展的必然趋势&#xff0c;数字孪生公司深圳华锐视点创新性地推出了景区三维可视化数字孪生平台&#xff0c;将线下的实体景区与线上的虚拟世界完美融合&#xff0c;引领智慧文旅新潮流。 我们运用先进的数字孪生、web3D开发和三维可视化等…

详解Qt中的鼠标事件

在Qt中&#xff0c;处理鼠标事件是构建交互式界面的关键。Qt提供了一系列与鼠标相关的事件处理函数&#xff0c;允许开发者捕获鼠标的各种动作&#xff0c;如按下、释放、移动、双击等。以下是鼠标事件的使用方法、技巧以及注意事项&#xff0c;并附带C代码示例。 基础使用方法…