基础IO(一)

news2025/2/23 13:48:19

基础IO(一)

  • 1.文件基础概念
  • 2.C语言接口回顾
  • 3.系统接口
  • 4.文件系统调用
  • 5.三个标准
  • 6.输出缓冲区

🌟🌟hello,各位读者大大们你们好呀🌟🌟
🚀🚀系列专栏:【Linux的学习】
📝📝本篇内容:文件基础概念;C语言接口回顾;系统接口;文件系统调用;三个标准;输出缓冲区
⬆⬆⬆⬆上一篇:C++中的继承
💖💖作者简介:轩情吖,请多多指教(> •̀֊•́ ) ̖́-

1.文件基础概念

①文件=属性+内容->针对文件的操作,对内容的操作,对属性的操作
②当文件没有被操作时,一般在磁盘
③当我们对文件进行操作时,文件需要在内存(冯诺依曼体系)
④先描述,构建在内存中的文件结构体struct file(文件一些属性可以从磁盘中来)
⑤每一个被打开的文件,都要在OS内对应文件对象的struct结构体,可以将所有的struct file结构体用某种数据结构连接起来,在OS内部,对被打开的文件进行管理,转换成了对链表的增删查改,总结来说就是文件被打开,OS要为被打开的文件,创建对应的内核数据结构
struct file
{
//各种属性、连接关系
}
⑥文件分为磁盘文件和被打开的文件(内存文件)
⑦文件是OS打开的,是用户(进程)让OS打开的
⑧都是进程和被打开文件的关系:struct task_struct和struct file

2.C语言接口回顾

①w:默认写方式打开文件,如果文件不存在,就创建它,默认如果只是打开,文件内容会被自动清空,每次写入都会从最开始进行写入
在这里插入图片描述
在这里插入图片描述

②a:不会清空文件,而是每一次写入都是从文件结尾写入的(追加)
在这里插入图片描述
在这里插入图片描述

3.系统接口

①int open(const char* pathname,int flags,mode_t mode);
在这里插入图片描述
在这里插入图片描述
其中mode是权限的设置,flags是位图的使用,int是32个比特位,我们可以用一个比特位表示一个标志位,可以看下面的代码来理解一下位图的使用

 1 #include <stdio.h>
  2 #define ONE 0x1//00000000000000000000000000000001
  3 #define TWO 0x2//00000000000000000000000000000010
  4 #define FOUR 0x4//00000000000000000000000000000100
  5 #define EIGHT 0x8//00000000000000000000000000001000
  6 void Print(int x)
  7 {
  8   //充当不同行为                                                                                                                                                    
  9   if(x&ONE)          
 10   {                  
 11     printf("NOE\n"); 
 12   }                  
 13                      
 14   if(x&TWO)          
 15   {                  
 16     printf("TWO\n"); 
 17   }                  
 18   if(x&FOUR)         
 19   {                  
 20     printf("FOUR\n");
 21   }                  
 22   if(x&EIGHT)        
 23   {                   
 24     printf("EIGHT\n");
 25   }                  
 26 }                    
 27 int main()           
 28 {                    
 29 Print(ONE|TWO|EIGHT);
 30                      
 31            
 32   return 0;
 33 }

在这里插入图片描述

O_WRONLY:只写,默认不会对原始文件内容做清空
O_CREAT:没有文件则创建文件
O_TRUNC:清空文件
O_APPEND:追加
O_RDONLY:只读
②ssize_t write(int fd,const void* buf,size_t count)
在这里插入图片描述
③ssize_t read(int fd, void *buf, size_t count);
在这里插入图片描述
代码测试:

//write的使用
#include <sys/types.h>
  2 #include <sys/stat.h>
  3 #include <fcntl.h>
  4 #include <unistd.h>
  5 #include <string.h>
  6 #include <stdio.h>
  7 int main()
  8 {
  9   mode_t mode=0000;//在本次进程中,权限掩码为0000
 10 int fd=open("log.txt",O_WRONLY|O_WRONLY|O_APPEND,mode);
 11 if(fd==-1)
 12 {
 13   return -1;
 14 }
 15 char arr[]="我是一个文件";
 16 write(fd,arr,strlen(arr));//']'\0'是C语言规定的,不是文件的规定                                                                                                     
 17 close(fd);//由于关闭文件的函数过于简单,我就不拿出来讲了
 18 
 19 
 20 
 21 
 22   return 0;
 23 }

在这里插入图片描述

//read的使用
#include <sys/types.h>
  2 #include <sys/stat.h>
  3 #include <fcntl.h>
  4 #include <unistd.h>
  5 #include <string.h>
  6 #include <stdio.h>
  7 int main()
  8 {
  9 int fd=open("log.txt",O_RDONLY);
 10 if(fd==-1)
 11 {
 12   return -1;
 13 }
 14 char arr[1024];
 15 int ret=read(fd,arr,1023);//']'\0'是C语言规定的,不是文件的规定
 16 if(ret>0)//read函数的返回值表示的是读取了多少字节                                                                                                                   
 17 arr[ret]='\0';                
 18 close(fd);//由于关闭文件的函数过于简单,我就不拿出来讲了
 19 printf("%s",arr);                                                                                                   
 20                                                                                                                     
 21                                                                                                                     
 22                                                                                                                     
 23   return 0;                                                                                                         
 24 } 

在这里插入图片描述
使用系统接口进行IO的时候一定要注意‘\0’的问题,这里我们无法做到按行读取,我们是整体读取的,其实本质上库函数底层也会调用系统调用

4.文件系统调用

任何一个进程,在启动的时候,默认会打开当前进程的三个文件:
在这里插入图片描述
现在来解释一下open的返回值:文件描述符,本质上其实是数组下标
在这里插入图片描述
我们使用OS的本质:都是通过进程的方式进行OS的访问的
在对于文件访问当中也会包含对于显示器,键盘等硬件的访问,而硬件访问就会比较复杂,因此在此类文件的struct file中会有对应的函数指针
在这里插入图片描述
FILE是一个结构体,C语言提供的
操作系统层面,我们必须要访问fd,我们才能找到文件
任何语言层访问外设或者文件,必须经历OS
在FILE里必定封装了fd

5.三个标准

进程中,文件描述符的分配规则:在文件描述符表中,最小的,没有被使用的数组元素,分配给新文件
其实本质上重定向的原理就是在上层无法感知的情况下,在OS内部,更改进程对应的文件描述符表中特定下标的指向!!!
其中stdout,cout本质他们内部的fd是1号文件描述符,他们都是向1号文件描述符对应的文件打印
stderr,cerr本质他们内部的fd是2号文件描述符,他们都是向2号文件描述符对应的文件打印
因此,输出重定向,只改的是1号对应的指向
代码验证:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
新的使用方法:
在这里插入图片描述
在这里插入图片描述
其中那行命令意思是把1号文件描述符所对应的指针变为log.txt的文件结构体指针,而2号文件描述符对应的指针同理
在这里插入图片描述
这是另一种用法,把一号文件描述符所对应的指针变为log.txt的文件结构体指针,2号文件描述符所对应的指针变为err.txt文件结构体指针
当我们真正要改变进程对应描述符表中特定下标的指向时,我们也可以使用函数
在这里插入图片描述
在这里插入图片描述
它的用法需要特别注意,不要搞反了,前半句的英语大致意思是,使新的fd变成旧的fd的拷贝,也就是说会有一个fd被覆盖,那我们可以明白newfd应该是你想要被修改的fd,实际上这个函数的本质就是数组对应下标的内容进行拷贝
在这里插入图片描述

在这里插入图片描述

6.输出缓冲区

C库会结合一定的刷新策略,将我们缓冲区中的数据写入给OS( write(FILE->fd,xxxxx) )
①无缓冲区 ②行缓冲区 ③全缓冲区
a.显示器采用的刷新策略:行缓冲。普通文件采用的刷新策略:全缓冲
b.缓冲区节省调用者的时间
c.在你进行fopen打开文件的时候,你会得到FILE结构体指针,缓冲区就在这个结构体中
d.当我们关闭文件的时候,C要帮我们进行冲刷缓冲区
e.在struct file里也有一个文件缓冲区,OS有自己的刷新策略,是不可见的且极其复杂
f.一共其实至少会有三次数据拷贝,从用户到语言,再从语言到struct file,再从struct file到磁盘
其中强制刷新struct file的缓冲区可以使用fsync函数

🌸🌸基础IO(一)的知识大概就讲到这里啦,博主后续会继续更新更多Linux的相关知识,干货满满,如果觉得博主写的还不错的话,希望各位小伙伴不要吝啬手中的三连哦!你们的支持是博主坚持创作的动力!💪💪

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

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

相关文章

股票K线基础知识2

光头光脚阳线 光头光脚阳线形态与特征描述 光头光脚阳线表示股票的最高价与收盘价相同&#xff0c;最低价与开盘价一样。光头光脚阳线上下不带影线&#xff0c;表明从一开盘买方就积极进攻&#xff0c;中间也可能出现买方与卖方的斗争&#xff0c;但买方发挥了最大力量。始终占…

18.JAVA之三大框架Spring、IOC和DI、拦截器、MVC项目、Mybatis持久层、动态SQL、SSM

一、Spring框架 1.1概述 其中最核心的是&#xff1a;IoC控制反转、DI依赖注入、Bean工厂、SpringAOP面向切面编程、事务控制。 Spring是一个开源框架&#xff0c;是为了解决企业应用程序开发复杂性而创建的。 SpringMVC框架用来接受浏览器的请求和给浏览器做出响应 Mybatis…

C++:设计一个线程安全的队列

文章目录 1. 目的2. 实现&#xff1f;验证&#xff01;makefileQueue 类的 public 成员单元测试 3. 实现 Queue 类的方案 1. 目的 串行的程序只用到单个 CPU 核心&#xff0c; 希望加速整个程序&#xff0c; 考虑使用多线程加速。典型情况下可以找到生产者、消费者&#xff0c…

基于ESP或ESP8266 单通道Lorawan网关硬件制作

软件代码设计资料下载链接》》 基于 Comresult PCB 的单通道网关 介绍 这是 ESP8266 LoRa 网关的最新版本。基于 ESP8266 mcu 的 LoRa 网关在过去几年里有了很大的发展。您想构建一个小型网关并保持尽可能多的 GPIO 引脚可用&#xff0c;Hallard 板是无与伦比的。另一种解决…

C++多态练习题

文章目录 1.虚函数的调用过程2.虚函数例题例题一例题二例题三例题四例题四 1.虚函数的调用过程 从汇编上面来看&#xff1a; []代表指针解引用操作 1.op指向test对象的首地址&#xff08;存放vptr&#xff09;&#xff0c;并存放在eax里面&#xff1b; 2.将eax所指之物(虚表…

使用不同的梯度下降法优化算法

本篇将使用以下几个梯度下降算法进行对比&#xff1a; 不使用任何的优化算法&#xff08;即整批数据集作为一次迭代更新梯度&#xff0c;也叫batch梯度下降&#xff0c;BGD&#xff09; mini-batch梯度下降法&#xff08;Mini-batchGD&#xff09; 使用具有动量的梯度下降算法&…

无标签背景图(负样本)的拼图代码

训练目标检测模型有个很令人头疼的问题&#xff0c;就是有些特征与要训练的特征较为相似的背景区域也被误检出来&#xff08;作为本应不该检测出来的负样本却被误检出为正样本的FP&#xff09;。 根据这一问题的解决办法&#xff0c;除了可以对正样本特征较为模糊或者有歧义的样…

Intel SGX学习笔记(2):用数组向Enclave传递5个数实现自增操作

写在前面 1、实现一个简单的Intel SGX的应用&#xff1a;非安全区定义初始化一个数组&#xff0c;数组里面存储5个数&#xff0c;然后向安全区&#xff08;enclave&#xff09;传入&#xff0c;在安全区中进行加减乘除&#xff0c;然后返回。 2、Intel SGX开发初学整体思路&a…

代码随想录算法训练营day39 | 62.不同路径,63. 不同路径 II

代码随想录算法训练营day39 | 62.不同路径&#xff0c;63. 不同路径 II 62.不同路径解法一&#xff1a;动态规划解法二&#xff1a;深度搜索&#xff08;明天补充&#xff09;解法三&#xff1a;数论&#xff08;明天补充&#xff09; 63. 不同路径 II解法一&#xff1a;动态规…

RuoYi-Vue下载与运行

一、源码下载 若依官网&#xff1a;RuoYi 若依官方网站 鼠标放到"源码地址"上&#xff0c;点击"RuoYi-Vue 前端分离版"。 跳转至Gitee页面&#xff0c;点击"克隆/下载"&#xff0c;复制HTTPS链接即可。 源码地址为&#xff1a;https://gitee.…

左值引用、右值引用,std::move() 的汇编解释

1&#xff1a;左值引用 引用其实还是指针&#xff0c;但回避了指针这个名字。由编译器完成从地址中取值。以vs2019反汇编&#xff1a; 如图&#xff0c;指针和引用的汇编代码完全一样。但引用在高级语言层面更友好&#xff0c;对人脑。比如可以少写一个 * 号和 -> 。 &…

F280049C实现Simulink调制,以及多个PWM实例之间的同步

文章目录 前言基本概念调制发波载波同步问题 前言 最近作实验碰到了载波不同步的问题&#xff0c;以前也有碰到过这个问题&#xff0c;现在终于解决了&#xff0c;做个记录。 为了以示区分&#xff0c;实例指ePWMx&#xff0c;x1,2,3,4,5,6,7,8&#xff1b;通道指ePWMxA/B&am…

如何使用jmeter进行压测

目录 1.概述 2.测试计划、线程组、取样器 3.调试运行 4.请求默认值 5.流量录制 6.模拟时间间隔 7.压力测试 8.报表 1.概述 一款工具&#xff0c;功能往往是很多的&#xff0c;细枝末节的地方也很多&#xff0c;实际的测试工作中&#xff0c;绝大多数场景会用到的也就是…

看大老如何用Postman+Jmeter实现接口实例

一、接口基础 为什么要单独测试接口&#xff1f; 1. 程序是分开开发的&#xff0c;前端还没有开发&#xff0c;后端已经开发完了&#xff0c;可以提前进入测试 2. 接口直接返回的数据------越底层发现bug&#xff0c;修复成本是越低的 3. 接口测试能模拟功能测试不能测到的异常…

数十位高级测工联合讲解Selenium自动化测试框架工作原理

一、Selenium是什么&#xff1f;   用官网的一句话来讲&#xff1a;Selenium automates browsers. Thats it&#xff01;简单来讲&#xff0c;Selenium是一个用于Web应用程序自动化测试工具。Selenium测试直接运行在浏览器中&#xff0c;就像真正的用户在操作浏览器一样。支持…

uvm寄存器模型

一、基础知识 前门访问与后门访问是两种寄存器的访问方式。 所谓前门访问, 指的是通过模拟cpu在总线上发出读指令, 进行读写操作。 在这个过程中, 仿真时间( $time函数得到的时间) 是一直往前走的。而后门访问是与前门访问相对的概念。 它并不通过总线进行读写操作, 而是…

2023/5/14周报

目录 摘要 论文阅读 1、标题和现存问题 2、准备知识 3、模型结构 4、实验准备 5、实验结果 深度学习 1、大气数据和水质数据 2、数据清洗 3、项目框架设定 总结 摘要 本周在论文阅读上&#xff0c;阅读了一篇时空图卷积网络:交通预测的深度学习框架的论文。文章的时…

oracle使用with as创建临时表

一、业务需求 在oracle项目的开发过程中&#xff0c;使用sql编写好对应的分析报表内容后&#xff0c;由于sql分析报表涉及到的一些线别丢失&#xff0c;导致呈现的报表分类统计时固定用醒目颜色标识的统计行数据显示错位&#xff1b;因此需要修复分析报表填充完整的线别。 二、…

LeetCode 62 不同路径

题目&#xff1a; 一个机器人位于一个 m x n 网格的左上角 &#xff08;起始点在下图中标记为 “Start” &#xff09;。机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角&#xff08;在下图中标记为 “Finish” &#xff09;。问总共有多少条不同的路径&#…

云上高校导航 小程序 开发教程

Gitee仓库&#xff1a;云上高校导航 GitHub仓库&#xff1a;云上高校导航 “云上高校导航”是一套基于小程序云开发的校园导航类系统开发方案&#xff0c;该开发方案可供开发者进行二次开发&#xff0c;用于解决师生和访客的校园出行需求。 项目优势及创新&#xff1a; 使…