当前位置: 首页 > news >正文

Linux 基础IO 二

1.文件描述符的分配规则

#include<stdio.h>
#include<string.h>
//#include<unistd.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>int main()
{close(1);//fd分配原则,从最小的开始,没有被占用的文件描述符给新打开的文件;int fd = open("log.txt", O_CREAT | O_TRUNC | O_RDONLY, 0666);if (fd < 0){perror("open");return 1;}//按道理,都应该是往显示器(标准输出)打印的;//但是下面的都写入到了log.txt中;//这叫什么呢?输出重定向;printf("fd:%d\n", fd);//stdout在FILE中的fd=1;而printf只向1中打印,他不管1到底是谁;1原本指向的是stdout,现在成了log.txt;fprintf(stdout, "hello printf\n");const char* s = "hello fwrite\n";fwrite(s, strlen(s), 1, stdout);return 0;
}

1.1输出重定向原理:文件操作前,进程会默认关联打开三个文件标准流文件;可是已经关闭了标准输出流,相当于把files_struct arrary指针数组中的'1'位置的数据置为了NULL;可是上层面已经把stdout 设置成了‘1’;根据文件描述符分配规则;所以就写入了log.txt;

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

1.2输入重定向

#include<stdio.h>
#include<string.h>
//#include<unistd.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>int main()
{close(0);int fd = open("log.txt", O_RDONLY);if (fd < 0){perror("open");return 1;}printf("fd:%d\n");char buffer[64];fgets(buffer, sizeof(buffer), stdin);printf("%s\n", buffer);return 0;
}

1.3追加重定向

#include<stdio.h>
#include<string.h>
//#include<unistd.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>int main()
{close(1);int fd = open("log.txt", O_APPEND |O_WRONLY |O_CREAT);if (fd < 0){perror("open");return 1;}fprintf(stdout,"you can see me sucessly\n");return 0;
}

2.以上全是野路子,是为了理解基本原理来写的;具体的看以下:

函数int  dup(int oldfd,int newfd)  :1:newfd  3:oldfd

#include<stdio.h>
#include<string.h>
//#include<unistd.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>int main(int argc,char* argv[])
{if (argc != 2) return 2;int fd = open("log.txt", O_CREAT |O_WRONLY |O_CREAT);if (fd < 0){perror("open");return 1;}fprintf(stdout,"%s\n",argv[1]);//stdout ->1->显示器dup2(fd, 1);  //重定向fprintf(stdout, "%s\n", argv[1]);close(fd)return 0;
}

3. 底层不同的硬件,一定对应着不同的操作方法。

但是不同的硬件都是外设,每一个设备的核心的访问函数都可以是  read  、write  (I/O)

所以:所有的设备,都有自己的read、write 但是代码的实现都不一样,就形成了类似C++的多态,调的函数名相同,但调用的不同——这样就是Linux下的一切皆文件——>VFS (virtual file system)虚拟文件系统

4.缓冲区问题

4.1什么是缓冲区? 答:就是一段内存空间

4.2为什么要有缓冲区?答:为了提高效率。如果cpu想向外设发送数据,肯定会等待多条数据一同发送到同一个外设中,而不是多次发送,所以提高了效率;主要是为了提高用户的响应速度;(写回模式)cpu太快了,相比之下磁盘太慢了,cpu等不起磁盘写入;

4.3缓冲区在哪里?谁提供?  答:

4.4缓冲区的发送数据的策率?答: 1.立即刷新  2.行刷新 (行缓冲,一般以\r,\n)3.满刷新(全缓冲:必须把缓冲区写满了,就刷新) 4.特殊情况:1.用户强制刷新(fflush) 2.进程退出,也会强制刷新;

4.5关于缓冲区的认知

一般而言,行缓冲的设备文件——是显示器

全缓冲的设备文件——磁盘文件

所有的设备,永远都倾向于全缓冲!因为缓冲区满了才刷新,意味着需要更少次的I/O操作——>更少的外设访问成本(提高效率)——cpu、内存和外设I/O的时候,数据量的大小不是主要矛盾,和外设预备I/O的过程才是最耗费时间的;其他的刷新策略,都是结合实际情况做的妥协;

显示器:是直接给用户看的,一方面要照顾效率,一方面要照顾用户体验;

极端情况下:是可以自定义规则的;

5.同样一个程序,向显示器打印输出4行文字,向普通文件(磁盘文件)打印输出7行,其中C的I/O接口打印了两次,系统接口打印了1次,和向显示器打印一样;

#include<stdio.h>
#include<string.h>
//#include<unistd.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>int main()
{//C语言提供的fprintf(stdout, "hello fprintf\n");printf("hello printf\n");const char* s = "hello fputs\n";fputs(s, stdout);//OS提供的const char* ss = "hello write\n";write(1, ss, strlen(ss));//注意我是在最后才调用的fork,上面的函数已经跑完了fork();//创建子进程;return 0;
}

问题1:上面的测试,并不能影响系统接口!

问题迁移:上述代码用到了几个知识? 答:写时拷贝技术,将缓冲区的数据考了一份给子进程;显示器和磁盘的刷新策略不同;文件输出重定向;————对程序进行了重定向,隐形的刷新策略变成了全缓冲,\n无意义了,fork的时候,函数已经执行完了,但是数据还未刷新,父进程里的缓冲区的数据,会被子进程接收,fork之后,父子分流,之后return,父子各自退出;进程退出,强行刷新;刷新是将缓冲区数据刷给内存,也是写时拷贝(不仅仅是改变变量数据)给子进程,所以打印了两份

如果有所谓的缓冲区,我们之前所谈的缓冲区,绝对不是由操作系统提供的,应该是由C标准库维护的,也就所谓的语言层面维护的;

5.1缓冲区在哪?答:进程启动连接了C标准库,缓冲区就是C标准库中开辟的一段内存空间,fputs数据,就是把数据写入到了这段内存空间中,在由标准库调用系统接口,压入磁盘;

5.2以上说的缓冲区是C标准库给我们提供的用户级缓冲区;也就是还存在内核级缓冲区;file结构体中也是存在内核缓冲区的,一旦使用write写入内核缓冲区,就代表和进程无关了;

5.3结构体file对象中,不止由fd,还有与缓冲区相关的类型指针

6.实战:自己设计用户缓冲区,minishell支持重定向;

#include<stdio.h>
#include<string.h>
//#include<unistd.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<assert.h>
#include<stdlib.h>struct my_file
{int fd;int end;  //当前缓冲区的结尾;char buffer[1024];
};
typedef struct my_file my_file;my_file* fopen_(const char* pathname, const char* mode) 
{assert(pathname);assert(mode);my_file* fp = NULL;if (strcmp(mode, "r") == 0)//C语言用的穷举,C++直接map,里面放lamda就行;{}else if (strcmp(mode, "w") == 0){int fd = open(pathname, O_WRONLY | O_TRUNC | O_CREAT,0666);if (fd >= 0){fp = (my_file*)malloc(sizeof(my_file));memset(fp, 0, sizeof(my_file));fp->fd = fd;}}return fp;
}
void fputs_(const char* message, my_file* fp)//这个接口是由C标准库来执行
{assert(message);assert(fp);strcpy(fp->buffer + fp->end, message);fp->end += strlen(message);//刷新策略;是用户通过执行C标准库中的代码逻辑,来完成刷新;//这里效率提高,体现在哪里?因为C提供了缓冲区,那么我们减少了IO的执行次数if (fp->fd == 0){//标准输入}else if (fp->fd == 1){//标准输出if (fp->buffer[fp->end - 1] == '\n'){write(fp->fd, fp->buffer, fp->end);fp->end = 0;}}else if (fp->fd == 2){//标准错误}else{//其他文件}
}
void fclose_(my_file* fp)
{assert(fp);fflush_(fp);close(fp->fd);free(fp);
}
void fflush_(my_file* fp)
{assert(fp);if (fp->end != 0){//暂且认为刷新——其实是把数据写到了内核write(fp->fd, fp->buffer, fp->end);syncfs(fp->fd);//将数据写入磁盘fp->end = 0;}}int main()
{my_file* fp = fopen_("./log.txt,", "w");if (fp == NULL){printf("open file error");return 1;}fputs_("hello world", fp);fclose_(fp);return 0;
}

相关文章:

Linux 基础IO 二

1.文件描述符的分配规则 #include<stdio.h> #include<string.h> //#include<unistd.h> #include<sys/types.h> #include<sys/stat.h> #include<fcntl.h>int main() {close(1);//fd分配原则&#xff0c;从最小的开始&#xff0c;没有被占用…...

找工作小项目:day15-macOS支持、完善逻辑

macOS支持、完善逻辑 目前的代码可以在Linux上完美运行编译&#xff0c;在Windows上也可以通过WSL编译运行源代码&#xff0c;但是在MacBook上却无法运行编译&#xff0c;这主要是由于macOS上没有epoll&#xff0c;取而代之的很相似的kqueue。由于操作系统不同&#xff0c;我们…...

植物大战僵尸杂交版 v2.0.88 mac版 Plants vs. Zombies 杂交版下载

特别注意&#xff1a;该游戏最低系统要求为macOS Sonoma 14.X&#xff0c;低于此系统版本的请勿下载&#xff01; 游戏介绍 植物大战僵尸杂交版是由B站UP主“潜艇伟伟迷”制作的一款结合了《植物大战僵尸》原有元素与创新玩法的游戏。这款游戏以其独特的“杂交”植物概念在B站…...

PHP中的while循环:用法、技巧与最佳实践

在PHP编程中&#xff0c;while循环是一种基本且常用的控制结构&#xff0c;用于重复执行代码块&#xff0c;直到指定条件为假。while循环在处理未知迭代次数的任务时特别有用&#xff0c;例如读取文件内容、处理用户输入或动态生成数据等。与for循环不同&#xff0c;while循环适…...

如何解决跨境传输常见的安全及效率问题?

在当今全球化的商业版图中&#xff0c;企业为了拓展国际市场和增强竞争力&#xff0c;跨境传输数据已成为一项不可或缺的业务活动。合格的数据跨境传输方案&#xff0c;应考虑以下要素&#xff1a; 法律合规性&#xff1a;确保方案符合所有相关国家的数据保护法律和国际法规&am…...

『大模型笔记』主成分分析(PCA)解释:简化机器学习中的复杂数据!

主成分分析(PCA)解释:简化机器学习中的复杂数据 文章目录 一. 主成分分析(PCA)解释:简化机器学习中的复杂数据!二. 参考文献一. 主成分分析(PCA)解释:简化机器学习中的复杂数据! 主成分分析(Principal Component Analysis,简称PCA)通过 将大型数据集中的维度减少…...

springboot与flowable(5):任务分配(表达式)

在做流程定义时我们需要给相关的用户节点指派对应的处理人。在flowable中提供了三种分配的方式。 一、固定分配 在分配用户时选择固定值选项确认即可。 二、表达式 1、值表达式 2、方法表达式 三、表达式流程图测试 1、导出并部署 导出流程图&#xff0c;复制到项目中 部署流…...

如何使用CCS9.3打开CCS3.0工程

如何使用CCS9.3打开CCS3.0工程 点菜单栏上的project&#xff0c;选择Import Legacy CCSv3.3 Porjects…&#xff0c;弹出对话框&#xff0c;通过Browse…按钮导入一个3.3版本的工程项目&#xff1b; 选择.pjt文件&#xff0c;选择Copy projects into worlkspace 右击选择P…...

Stable Diffusion 3 Medium 模型

开源SD3&#xff0c;中型版本&#xff0c;20亿参数&#xff0c;Stable Diffusion 3 Medium&#xff0c;系统内存要求32G&#xff0c;显卡6G。 a female character with long, flowing hair that appears to be made of ethereal, swirling patterns resembling the Northern Li…...

数据分析------统计学知识点(五)

回归算法 想象一下&#xff0c;你和朋友在讨论:大学生活中&#xff0c;每天学习的时间是否真的能影响期末成绩?这个问题看似简单&#xff0c;实则包含了一个潜在的关系:学习时间与成绩之间的联系。我们想要知道&#xff0c;增加学习时间是否会提高成绩&#xff0c;以及这种提…...

Superset二次开发之Git篇 git remote

背景:从GitHub clone Superset项目,基于3.0版本做二次开发,后续通过其他方式把3.0版本未做任何修改过的原始代码上传到企业GitLab库develop分支 任务:本地代码推送到GitLab库develop分支,但是两者似乎没有任何关联关系 操作步骤 克隆 Superset 3.0 版本的项目到本地: …...

记录一下PHP使用微信小程序支付

记录一下PHP使用微信小程序支付V3版本经历 官方文档&#xff1a;https://pay.weixin.qq.com/wiki/doc/apiv3/open/pay/chapter2_8_0.shtml 请详细查看文档中小程序支付接入前准备&#xff08;https://pay.weixin.qq.com/wiki/doc/apiv3/open/pay/chapter2_8_1.shtml&#xff…...

【数据结构初阶】 --- 单链表

关于链表你应该先了解这些 下图描述了物理模型和逻辑模型&#xff0c;大多数常见的其实是逻辑模型&#xff0c;但这对初学者或者掌握不扎实的同学不太友好&#xff0c;所以这里我重点讲解物理模型&#xff0c;当了解了这些细节&#xff0c;以后做题或是什么就直接画逻辑模型就…...

并发、多线程、HTTP连接数有何关系?

在计算机领域&#xff0c;"并发"、"多线程"和"HTTP连接数"是三个重要的概念&#xff0c;它们之间存在着密切的关系。本文将探讨这三者之间的联系以及它们在现代计算机系统中的作用。 一、并发的概念 并发是指系统能够同时处理多个任务或事件的能…...

鸿蒙轻内核Kconfig使用笔记

鸿蒙轻内核使用Kconfig进行图形化配置&#xff0c;本文专门讲解下鸿蒙轻内核LiteOS-M和LiteOS-A的图形化配置方法。本文中所涉及的源码&#xff0c;均可以在开源站点 https://gitee.com/openharmony/kernel_liteos_a 、 https://gitee.com/openharmony/kernel_liteos_m 获取。本…...

react 0至1 案例

/*** 导航 Tab 的渲染和操作** 1. 渲染导航 Tab 和高亮* 2. 评论列表排序* 最热 > 喜欢数量降序* 最新 > 创建时间降序* 1.点击记录当前type* 2.通过记录type和当前list中的type 匹配*/ import ./App.scss import avatar from ./images/bozai.png import {useState} …...

基于MCU平台的HMI开发的性能优化与实战(上)

随着汽车座舱智能化的不断演进&#xff0c;车内显示设备的数量显著增加&#xff0c;从传统的仪表盘和中控屏扩展至空调控制、扶手、副驾驶区域以及抬头显示&#xff08;HUD&#xff09;等多样化的显示单元。为了有效支持这些功能单元&#xff0c;同时控制整车成本&#xff0c;越…...

【Tkinter界面】Canvas 图形绘制(02/5)

文章目录 一、说明二、几何时使用 Canvas 组件2.1 用法2.2 简单范例2.3 对象移动2.4 对象删除2.5 文字对象显示 三、画布和画布对象3.1 画布生成函数原型3.2 使用create_xxx()方法3.3 对参数**options的解释 一、说明 Canvas&#xff08;画布&#xff09;组件为 Tkinter 的图形…...

1_常见指令【Linux中常见30个指令的学习和使用】【万字长文】

常见指令以及权限理解 开始学习linux前的注意事项 在学习linux之前&#xff0c;我们要知道linux是一个操作系统。 那操作系统是什么呢&#xff1f;&#xff08;这里只做大概了解&#xff09; 操作系统就是一个管理软硬件的软件。 它对上提供良好&#xff08;稳定、高效、安…...

每日复盘-202406014

今日关注: 这几天市场打板情绪环境转好,轻仓试错 20240614 六日涨幅最大: ------1--------301036--------- 双乐股份 五日涨幅最大: ------1--------301036--------- 双乐股份 四日涨幅最大: ------1--------301036--------- 双乐股份 三日涨幅最大: ------1--------301082-…...

XML Group端口详解

在XML数据映射过程中&#xff0c;经常需要对数据进行分组聚合操作。例如&#xff0c;当处理包含多个物料明细的XML文件时&#xff0c;可能需要将相同物料号的明细归为一组&#xff0c;或对相同物料号的数量进行求和计算。传统实现方式通常需要编写脚本代码&#xff0c;增加了开…...

华为云AI开发平台ModelArts

华为云ModelArts&#xff1a;重塑AI开发流程的“智能引擎”与“创新加速器”&#xff01; 在人工智能浪潮席卷全球的2025年&#xff0c;企业拥抱AI的意愿空前高涨&#xff0c;但技术门槛高、流程复杂、资源投入巨大的现实&#xff0c;却让许多创新构想止步于实验室。数据科学家…...

Lombok 的 @Data 注解失效,未生成 getter/setter 方法引发的HTTP 406 错误

HTTP 状态码 406 (Not Acceptable) 和 500 (Internal Server Error) 是两类完全不同的错误&#xff0c;它们的含义、原因和解决方法都有显著区别。以下是详细对比&#xff1a; 1. HTTP 406 (Not Acceptable) 含义&#xff1a; 客户端请求的内容类型与服务器支持的内容类型不匹…...

8k长序列建模,蛋白质语言模型Prot42仅利用目标蛋白序列即可生成高亲和力结合剂

蛋白质结合剂&#xff08;如抗体、抑制肽&#xff09;在疾病诊断、成像分析及靶向药物递送等关键场景中发挥着不可替代的作用。传统上&#xff0c;高特异性蛋白质结合剂的开发高度依赖噬菌体展示、定向进化等实验技术&#xff0c;但这类方法普遍面临资源消耗巨大、研发周期冗长…...

安宝特方案丨XRSOP人员作业标准化管理平台:AR智慧点检验收套件

在选煤厂、化工厂、钢铁厂等过程生产型企业&#xff0c;其生产设备的运行效率和非计划停机对工业制造效益有较大影响。 随着企业自动化和智能化建设的推进&#xff0c;需提前预防假检、错检、漏检&#xff0c;推动智慧生产运维系统数据的流动和现场赋能应用。同时&#xff0c;…...

STM32标准库-DMA直接存储器存取

文章目录 一、DMA1.1简介1.2存储器映像1.3DMA框图1.4DMA基本结构1.5DMA请求1.6数据宽度与对齐1.7数据转运DMA1.8ADC扫描模式DMA 二、数据转运DMA2.1接线图2.2代码2.3相关API 一、DMA 1.1简介 DMA&#xff08;Direct Memory Access&#xff09;直接存储器存取 DMA可以提供外设…...

【Java_EE】Spring MVC

目录 Spring Web MVC ​编辑注解 RestController RequestMapping RequestParam RequestParam RequestBody PathVariable RequestPart 参数传递 注意事项 ​编辑参数重命名 RequestParam ​编辑​编辑传递集合 RequestParam 传递JSON数据 ​编辑RequestBody ​…...

浪潮交换机配置track检测实现高速公路收费网络主备切换NQA

浪潮交换机track配置 项目背景高速网络拓扑网络情况分析通信线路收费网络路由 收费汇聚交换机相应配置收费汇聚track配置 项目背景 在实施省内一条高速公路时遇到的需求&#xff0c;本次涉及的主要是收费汇聚交换机的配置&#xff0c;浪潮网络设备在高速项目很少&#xff0c;通…...

基于Java+VUE+MariaDB实现(Web)仿小米商城

仿小米商城 环境安装 nodejs maven JDK11 运行 mvn clean install -DskipTestscd adminmvn spring-boot:runcd ../webmvn spring-boot:runcd ../xiaomi-store-admin-vuenpm installnpm run servecd ../xiaomi-store-vuenpm installnpm run serve 注意&#xff1a;运行前…...

Xela矩阵三轴触觉传感器的工作原理解析与应用场景

Xela矩阵三轴触觉传感器通过先进技术模拟人类触觉感知&#xff0c;帮助设备实现精确的力测量与位移监测。其核心功能基于磁性三维力测量与空间位移测量&#xff0c;能够捕捉多维触觉信息。该传感器的设计不仅提升了触觉感知的精度&#xff0c;还为机器人、医疗设备和制造业的智…...