[Linux]基础IO详解(系统文件I/O接口、文件描述符、理解重定向)

        hello,大家好,这里是bang___bang_ ,今天和大家谈谈Linux中的基础IO,包含内容有对应的系统文件I/O接口,文件描述符,理解重定向。

  

目录

1️⃣初识文件

2️⃣ 系统文件I/O接口

🍙open

🍙write

🍙read

🍙close

3️⃣文件描述符

🍙0&1&2

🍙内核中文件描述符的探究

🍙分配规则

4️⃣重定向

🍙重定向现象 

🍙重定向的本质

🍙dup2系统调用


1️⃣初识文件

        文件=内容+属性(属性也是数据)

        文件的所有操作:a.对内容    b.对属性

        文件在磁盘(硬件)上放着,我们访问文件,先写代码->编译->exe->运行->访问文件。

        本质上是 进程 在访问文件。

Linux下一切皆文件。曾经我们理解的文件就是磁盘上的那些普通文件能read,write。

        在C语言中,我们对显示器有方法:printf->这是write(output);键盘:scanf->这是read(input)。也就是说我们的显示器和键盘也是文件。

        站在系统的角度来说:我们的程序要加载到内存,键盘相当于把我们的数据输交给内存(input),而内存把读取到的数据刷新到文件或者显示器当中(output)。

系统角度:能够被input读取,或者能够被output写出的设备就叫做文件!

2️⃣ 系统文件I/O接口

        在C语言中,文件操作接口有fopen,fwrite,fprintf,fclose等等,实际上这些接口都是封装了系统I/O接口。

🍙open

pathname: 要打开或创建的目标文件
flags: 打开文件时,可以传入多个参数选项
参数 :
         O_RDONLY: 只读打开
         O_WRONLY: 只写打开
         O_RDWR : 读,写打开
        O_RDONLY  O_WRONLY  O_RDWR 这三个常量,必须指定一个且只能指定一个
         O_CREAT : 若文件不存在,则创建它。需要使用 mode 选项,来指明新文件的访问权限
         O_APPEND: 追加写
        O_TRUNC: 清空文件
mode: 为新建文件设置权限

问题:如何实现flags传入多个参数选项呢?

答:采用位图的思想,flags的参数实际上是一个int类型的数,参数之间进行|运算,就能实现传入多个参数的效果。

源码定义

🌰O_WRONLY | O_CREAT 

模拟结果

检测是否有当前状态,只需要使用flag&状态的值。

0110 0101 & 0000 0001 = 0000 0001 有O_WRONLY状态

0110 0101 & 0110 0100 = 0110 0100 有O_CREAT状态

open函数图中我框选了返回值为一个文件描述符,在下面讲解。

🌰简单使用open

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

int main()
{
    int fd=open("log.txt",O_WRONLY | O_CREAT,0666);
    assert(fd!=-1);
    printf("open sucess! fd:%d\n",fd);
    return 0;    
}

权限解释

🍙write

 功能:把缓冲区buf的前count字节写入与文件描述符fd关联的文件中。它返回实际写入的字节数。

🌰测试write

#include<stdio.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<assert.h>
#include<string.h>
int main()
{
    int fd=open("log.txt",O_WRONLY | O_CREAT | O_TRUNC,0666);
    assert(fd!=-1);
    printf("open sucess! fd:%d\n",fd);
    const char* buf="This is a test\n";
    write(fd,buf,strlen(buf));
    return 0;    
}

🍙read

功能:从与文件描述符fd相关联的文件中读取count个字节的数据。并把它放入到数据区buf中。

🌰测试read,读取上面write写的内容

int main()
{
    int fd=open("log.txt",O_RDONLY);
    assert(fd!=-1);
    printf("open sucess! fd:%d\n",fd);

    char res[64];
    read(fd,res,sizeof(res));
    printf("res:%s",res);
    return 0;    
}

🍙close

 

功能:将文件描述符fd相关联的文件关闭。

🌰close操作演示

int main()
{
    int fd=open("log.txt",O_RDONLY);
    assert(fd!=-1);
    printf("open sucess! fd:%d\n",fd);
    close(fd);
    return 0;    
}

3️⃣文件描述符

🍙0&1&2

🌰fd的显示问题:

int main()
{
    int fd1=open("log1.txt",O_WRONLY | O_CREAT | O_TRUNC,0666);
    int fd2=open("log2.txt",O_WRONLY | O_CREAT | O_TRUNC,0666);
    int fd3=open("log3.txt",O_WRONLY | O_CREAT | O_TRUNC,0666);
    int fd4=open("log4.txt",O_WRONLY | O_CREAT | O_TRUNC,0666);
    assert(fd1!=-1);
    assert(fd2!=-1);
    assert(fd3!=-1);
    assert(fd4!=-1);
    printf("open sucess! fd1:%d\n",fd1);
    printf("open sucess! fd2:%d\n",fd2);
    printf("open sucess! fd3:%d\n",fd3);
    printf("open sucess! fd4:%d\n",fd4);
    close(fd1);
    close(fd2);
    close(fd3);
    close(fd4);
    return 0;    
}

问题:为什么fd是从3开始? 

答:实际上C/C++程序默认会打开三个文件流:标准输入stdin(0),标准输出stdout(1),标准错误stderr(2)

0,1,2一般对应的物理设备是:键盘,显示器,显示器。

🍙内核中文件描述符的探究

在上面我们可以发现文件描述符fd就是一个小整数,那么在内核中文件描述符究竟是什么呢?

内核结构
        当我们打开文件时,操作系统在内存中要创建相应的数据结构来描述目标文件。于是就有了file结构体。表示一个已经打开的文件对象。而进程执行 open 系统调用,所以必须让进程和文件关联起来。每个进程都有一个指针*files, 指向一张表 files_struct, 该表最重要的部分就是包涵一个指针数组,每个元素都是一个指向打开文件的指针!所以,本质上, 文件描述符就是该数组的下标 。所以,只要拿着文件描述符,就可以找到对应的文件。
抽象结构图

🍙分配规则

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

🌰验证分配规则,关闭文件0,进行分配。

int main()
{
    close(0);
    int fd=open("log1.txt",O_WRONLY | O_CREAT | O_TRUNC,0666);
    assert(fd!=-1);
    printf("open sucess! fd:%d\n",fd);
    close(fd);

    return 0;    
}

问题:如果关闭文件描述符1,为什么没有输出显示。

答:文件描述符1对应显示器,关闭后自然就不会有内容显示到显示器了,但是也没有显示到文件log.txt中。

4️⃣重定向

🍙重定向现象 

问题:上面例子中内容没有显示到显示器和文件log.txt中,那么内容实际上在哪个地方?

答:在文件的缓冲区中

那是不是意味着我们刷新缓冲区就可以将内容显示出来?

int main()
{
    close(1);
    int fd=open("log.txt",O_WRONLY | O_CREAT| O_TRUNC,0666);
    assert(fd!=-1);
    printf("open sucess! fd:%d\n",fd);
    fflush(stdout);//刷新缓冲区
    close(fd);
    return 0;    
}

刷新后成功输出,内容本来应该输出到显示屏,但是现在输出到了log.txt这实际上就是输出重定向!!!(O_CREAT创建文件,O_TRUNC刷新文件,实现C语言中的w模式;O_APPEND追加内容,实现C语言中的a模式)

🍙重定向的本质

重定向的本质,其实是在OS内部,更改fd对应的内容的指向!!

🍙dup2系统调用

在重定向中,我们通常不使用close关闭fd,再重定向,而是直接使用系统调用dup2来重定向。 

将oldfd的内容给newfd,即newfd对应内容指向oldfd

🌰dup2系统调用测试

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

int main()
{
    int fd=open("log.txt",O_WRONLY | O_CREAT| O_TRUNC,0666);
    assert(fd!=-1);
    dup2(fd,1);
    printf("open sucess! fd:%d\n",fd);
    close(fd);
    return 0;    
}
dup2实现重定向

文末结语,本文讲解Linux的基础IO,包含内容:初识文件,系统文件I/O接口open、read、write、close,文件描述符的详细讲解以及文件描述符的分配规则,重定向现象的演示及重定向的本质讲解,实现重定向的系统调用dup2。如有需要,希望能有所帮助!!!

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

小程序学习(五):WXSS模板语法

1.什么是WXSS WXSS是一套样式语言,用于美化WXML的组件样式,类似于网页开发中的CSS 2.WXSS和CSS的关系 WXSS模板样式-rpx 3.什么是rpx尺寸单位 4.rpx的实现原理 5.rpx与px之间的单位换算* WXSS模板样式-样式导入 6.什么是样式导入 使用WXSS提供的import语法,可以导入外联的样式…

华为云低代码平台Astro Canvas 搭建汽车展示大屏——实验指导手册

实验背景 大屏应用Astro Canvas是华为云低代码平台Astro的子服务之一&#xff0c;是以数据可视化为核心&#xff0c;以屏幕轻松编排&#xff0c;多屏适配可视为基础&#xff0c;用户可通过图形化界面轻松搭建专业水准的数据可视化大屏。例如汽车展示大屏、监控大屏、项目开发大…

数据结构——绪论

一、绪论 &#xff08;一&#xff09;基本概念 数据&#xff1a;数据是对客观事物的符号表示&#xff0c;在计算机科学中是指所有能输入到计算机中并被计算机程序处理的符号的总称。 数据元素&#xff1a;数据元素是数据的基本单位&#xff0c;在计算机程序中通常作为一个整…

消息队列总结(4)- RabbitMQ Kafka RocketMQ高性能方案

1.RabbitMQ的高性能解决方案 1.1 发布确认机制 RabbitMQ提供了3种生产者发布确认的模式&#xff1a; 简单模式&#xff08;Simple Mode&#xff09;&#xff1a;生产者发送消息后&#xff0c;等待服务器确认消息已经被接收。这种模式下&#xff0c;生产者发送消息后会阻塞&am…

学习系统编程No.34【线程同步之信号量】

引言&#xff1a; 北京时间&#xff1a;2023/7/29/16:34&#xff0c;一切尽在不言中&#xff0c;前几天追了几部电视剧&#xff0c;看了几部电影&#xff0c;刷了n个视屏&#xff0c;在前天我们才终于从这快乐的日子里恢复过来&#xff0c;然后看了两节课&#xff0c;也就是上…

真机搭建中小网络

这是b站上的一个视频&#xff0c;演示了如何搭建一个典型的中小网络&#xff0c;供企业使用 一、上行端口&#xff1a;上行端口就是连接汇聚或者核心层的口&#xff0c;或者是出广域网互联网的口。也可理解成上传数据的端口。 二、下行端口&#xff1a;连接数据线进行下载的端…

Scratch Blocks自定义组件之「旋律播放」

一、背景 看到microbit edit有旋律编辑器&#xff0c;就在scratch块中也写了一个&#xff0c;如下图所示 这是我写的 这是Micro:bit的 二、功能配置说明 支持8个音符8拍旋律控制 三、使用说明 &#xff08;1&#xff09;引入添加field_tone.js到core文件夹中&#xff0c;代码在…

信息系统网络安全整改方案

第1章 项目概述 1.1 项目目标 本方案将通过对公司网络信息系统的安全现状进行分析工作&#xff0c;参照国家信息系统等级保护要求&#xff0c;找出信息系统与安全等级保护要求之间的差距&#xff0c;给出相应的整改意见&#xff0c;推动 XX 企业公司网络信息系统安全整改工作的…

计算机毕设 深度学习手势识别 - yolo python opencv cnn 机器视觉

文章目录 0 前言1 课题背景2 卷积神经网络2.1卷积层2.2 池化层2.3 激活函数2.4 全连接层2.5 使用tensorflow中keras模块实现卷积神经网络 3 YOLOV53.1 网络架构图3.2 输入端3.3 基准网络3.4 Neck网络3.5 Head输出层 4 数据集准备4.1 数据标注简介4.2 数据保存 5 模型训练5.1 修…

与“云”共舞,联想凌拓的新科技与新突破

伴随着数字经济的高速发展&#xff0c;IT信息技术在数字中国建设中起到的驱动和支撑作用也愈发凸显。特别是2023年人工智能和ChatGPT在全球的持续火爆&#xff0c;更是为整个IT产业注入了澎湃动力。那么面对日新月异的IT信息技术&#xff0c;再结合疫情之后截然不同的经济环境和…

【抖音小游戏】 Unity制作抖音小游戏方案 最新完整详细教程来袭【持续更新】

前言 【抖音小游戏】 Unity制作抖音小游戏方案 最新完整详细教程来袭【持续更新】一、相关准备工作1.1 用到的相关网址1.2 注册字节开发者后台账号 二、相关集成工作2.1 下载需要的集成资源2.2 安装StarkSDK和starksdk-unity-tools工具包2.3 搭建测试场景 三、构建发布3.1 发布…

【深度学习】MAT: Mask-Aware Transformer for Large Hole Image Inpainting

论文&#xff1a;https://arxiv.org/abs/2203.15270 代码&#xff1a;https://github.com/fenglinglwb/MAT 文章目录 AbstractIntroductionRelated WorkMethod总体架构卷积头Transformer主体Adjusted Transformer Block Multi-Head Contextual Attention Style Manipulation Mo…

探索Vue组件通信的秘密:打破隔阂,实现数据共享

一、Vue组件通信 每个组件都有自己的数据, 提供在data中, 每个组件的数据是独立的, 组件数据无法互相直接访问 (合理的)但是如果需要跨组件访问数据, 就需要用到组件通信 要是有一万个商品&#xff1f;&#xff1f;&#xff1f;&#xff1f;就要写一万个吗&#xff1f;函数调用…

KubeSphere 3.4.0 发布:支持 K8s v1.26

2023 年 07 月 26 日&#xff0c;KubeSphere 开源社区激动地向大家宣布&#xff0c;KubeSphere 3.4.0 正式发布&#xff01; 让我们先简单回顾下之前三个大版本的主要变化&#xff1a; KubeSphere 3.1.0 新增了“边缘计算”、“计量计费” 等功能&#xff0c;将 Kubernetes 从…

myeclipse的Debug模式

1.表示当前实现继续运行直到下一个断点&#xff0c;快捷键为F8。 2.表示打断整个进程 3.表示进入当前方法&#xff0c;快捷键为F5。 4.表示运行下一行代码&#xff0c;快捷键为F6。 5.表示退出当前方法&#xff0c;返回到调用层&#xff0c;快捷键为F7。 6.表示当前线程的…

kotlin 编写一个简单的天气预报app(五)增加forcast接口并显示

参考资料 OpenWeatherMap提供了一个/forecast接口&#xff0c;用于获取未来几天的天气预报。你可以使用HTTP GET请求访问该接口&#xff0c;并根据你所在的城市或地理坐标获取相应的天气数据。 以下是一个示例请求的URL和一些常用的参数&#xff1a; URL: http://api.openwe…

我的创作纪念日——256天

机缘 最开始我写博客没有什么特别的原因&#xff0c;主要是因为以下几点&#xff1a; 练习自己的语言组织能力 记录自己学习生活中学到的知识 为和我同一个学习阶段的朋友提供帮助 事实上最开始我根本不指望我的博客有多少人看&#xff0c;主要是想找一个好的保存 Markdown 笔…

花费7元训练自己的GPT 2模型

在上一篇博客中&#xff0c;我介绍了用Tensorflow来重现GPT 1的模型和训练的过程。这次我打算用Pytorch来重现GPT 2的模型并从头进行训练。 GPT 2的模型相比GPT 1的改进并不多&#xff0c;主要在以下方面&#xff1a; 1. GPT 2把layer normalization放在每个decoder block的前…

PHP最简单自定义自己的框架(一)

为啥要定义自己的框架&#xff1a; 定制化需求&#xff1a;每个项目都有不同的需求和特点&#xff0c;使用通用的框架可能无法满足所有的要求。自定义框架可以根据具体需求进行定制&#xff0c;提供更加灵活和符合项目需求的解决方案。学习和成长&#xff1a;自定义框架是一个很…

STM32存储左右互搏 I2C总线读写EEPROM ZD24C1MA

STM32存储左右互搏 I2C总线读写EEPROM ZD24C1MA 在较低容量存储领域&#xff0c;EEPROM是常用的存储介质&#xff0c;不同容量的EEPROM的地址对应位数不同&#xff0c;在发送字节的格式上有所区别。EEPROM是非快速访问存储&#xff0c;因为EEPROM按页进行组织&#xff0c;在连…