【linux】重定向|缓冲区

read函数

在这里插入图片描述

将文件标识符为fd的文件内容读到buf中去,读count个,read的返回值是实际读到的个数,有可能文件中没有count个,但是read返回的还是实际读到的个数

stat函数

在这里插入图片描述

调用这个函数可以查到对应文件的属性,比方说文件大小
pathname:用于指定一个需要查看属性的文件路径。
buf:struct stat 类型指针,用于指向一个 struct stat 结构体变量。调用 stat 函数的时候需要传入一个 struct stat 变量的指针,获取到的文件属性信息就记录在 struct stat 结构体中。
返回值:成功返回 0;失败返回-1,并设置 error。

  1 #include<stdio.h>2 #include <unistd.h>3 #include <sys/types.h>4 #include <sys/stat.h>5 #include <fcntl.h>6 #include<stdlib.h>7 const char* filename="log.txt";8 int main()9 {10 struct stat st;11 int n=stat(filename,&st);12 if(n<0) return 1;13 printf("file size:%lu\n",st.st_size);14 int fd=open(filename,O_RDONLY);15 if(fd<0)16 {17 perror("open");18 return 2;19 }20 printf("fd:%d\n",fd);21 char* file_buffer=(char*)malloc(st.st_size);                                                                       22 n=read(fd,file_buffer,st.st_size);23 if(n>0)24 {25 26 file_buffer[n]='\0';27 }27 printf("%s",file_buffer); 28 free(file_buffer);29 close(fd);30 return 0;31 }32 

代码解释:stat函数获取filename(log.txt)的文件属性,然后就可以直接获取文件大小在结构体变量中st.st_size,打印文件的文件标识符fd,malloc一个和文件大小一样的file_buffer模拟缓冲区,通过read函数将文件内容读到file_buffer中。read读取实际读到的大小,返回为实际大小n,并在模拟的缓冲区的最后加’\0’,释放file_buffer空间,关闭文件.
在这里插入图片描述

如果要查看文件对应的属性结构体在/usr/include/libio.h
在这里插入图片描述


重定向

    1 #include<stdio.h>2 #include <sys/types.h>3 #include <sys/stat.h>4 #include <fcntl.h>5 #include <unistd.h>6 int main()7 {8 close(1);9 10 int fd=open("log.txt",O_CREAT|O_TRUNC|O_WRONLY,0666);11 if(fd<0)12 {13 perror("open fail");14 }15 const char* buf="hello world";16 write(1,buf,sizeof(buf));                                                                                        17 printf("log.txt:fd:%d",fd);   18 } 

代码解释:我们关闭文件标识符为1的屏幕,根据文件描述符的分配规则:查自己的文件描述表,分配最小的没有被使用过的fd,于是新创建的文件的文件描述符被分配1,以至于本来要显示在屏幕上的东西,显示在了文件log.txt中,这就叫做重定向
在这里插入图片描述

在这里插入图片描述


使用重定向并非要关闭一个文件描述符对应的文件,让另一个来替代这个被关闭的文件,我们可以使用dup2函数也能实现重定向
在这里插入图片描述

dup2函数原理说明:
在这里插入图片描述

在这里插入图片描述
重定向的本质:是在内核中改变文件描述符特定下标的内容,和上层无关,文件描述符下标对应内容的拷贝

使用dup2实现的重定向和close(1)重新分配一样的效果

  1 #include<stdio.h>2 #include <sys/types.h>3 #include <sys/stat.h>4 #include <fcntl.h>5 #include <unistd.h>6 int main()7 {8 9 10 int fd=open("log.txt",O_CREAT|O_TRUNC|O_WRONLY,0666);11 if(fd<0)                                                                                                           12 {13 perror("open fail");14 }15 dup2(fd,1);16 const char* buf="hello world";17 write(1,buf,sizeof(buf));18 printf("log.txt:fd:%d",fd);19 }

在这里插入图片描述

在这里插入图片描述


缓冲区

  1 #include<stdio.h>2 #include <sys/types.h>3 #include <sys/stat.h>4 #include <fcntl.h>5 #include <unistd.h>6 7 int main()8 {9   close(1);                                                                                                        10 int fd=open("log.txt",O_CREAT|O_WRONLY|O_TRUNC,0666);11 if(fd<0)12 {perror("open fail");13 return 1;}14 printf("printf,fd:%d\n",fd);15 fprintf(stdout,"fprintf,fd:%d\n",fd);16 close(fd);17 return 0;18 }

代码解释:我们关闭屏幕,让本来打印到屏幕上去的,打印到文件log.txt中去.

在这里插入图片描述

在这里插入图片描述
我们发现没有打印到文件中去

  1 #include<stdio.h>                                                                          2 #include <sys/types.h>                                                                     3 #include <sys/stat.h>                                                                      4 #include <fcntl.h>                                                                         5 #include <unistd.h>                                                                        6                                                                                            7 int main()                                                                                 8 {                                                                                          9   close(1);                                                                                10 int fd=open("log.txt",O_CREAT|O_WRONLY|O_TRUNC,0666);                                      11 if(fd<0)                                                                                   12 {perror("open fail");                                                                      13 return 1;}                                                                                 14 printf("printf,fd:%d\n",fd);                                                               15 fprintf(stdout,"fprintf,fd:%d\n",fd);                                                      16 fflush(stdout);                                                                                                    17 close(fd);                                                        18 return 0;                                                         19 }  

当我加上一个fflush后,就出现了,到底是为什么呢???

在这里插入图片描述

在这里插入图片描述


这里就要提出缓冲区这个概念了,实际上存在一个语言级别的缓冲区,当我们使用printf,fprintf的时候,我们是将对应内容写到了语言级别的缓冲区里面,并没有写到操作系统对应内核的操作系统里面,如果此时不加fflush的话,就关闭文件,对应文件的内核缓冲区中没有数据,而文件中写入的数据,都是文件对应的内核缓冲区中冲刷过来的.这里fflush的作用是将语言级别的缓冲区的内容冲刷到对应文件的内核缓冲区中去

画一个图理解一下
在这里插入图片描述

在这里插入图片描述


缓冲区知识总结:缓冲区包括用户级缓冲区(语言层面的)和内核级缓冲区,主要作用是解耦和提高效率,提高了使用者的效率,使用者只需将printf将内容放到用户级缓冲区中,剩下的的事情操作系统帮你干,提高了刷新IO的效率
缓冲区是什么?
一段内存空间
为什么要存在缓冲区?
给上层提供高效的IO体验,间接提供整体效率
刷新策略
1.立即刷新
2.行刷新(方便用户阅读习惯)
3.全缓冲:缓冲区写满,才刷新(普通文件采用这个)
特殊情况:
进程退出,系统会自动刷新(强制)


 1 #include<stdio.h>2 #include <unistd.h>3 int  main()4 {5 fprintf(stdout,"hello fprintf\n");6 printf("hello printf\n");7 const char* buf="hello write\n";8 write(1,buf,sizeof(buf));                                                                                          9 return 0;10 11 12 }
  1 #include<stdio.h>2 #include <unistd.h>3 #include<string.h>4 int  main()5 {                                                                                                                  6 fprintf(stdout,"hello fprintf\n");7 printf("hello printf\n");8 const char* buf="hello write\n";9 write(1,buf,strlen(buf));10 fork();11 return 0;12 13 14 }

在这里插入图片描述
在这里插入图片描述


  1 #include<stdio.h>2 #include <unistd.h>3 #include<string.h>4 #include <sys/types.h>5 #include <sys/stat.h>6 #include <fcntl.h>7 int  main()8 {9   close(1);10 int fd=open("log.txt",O_CREAT|O_WRONLY|O_TRUNC,0666);11 fprintf(stdout,"hello fprintf\n");                                                                                 12 printf("hello printf\n");13 const char* buf="hello write\n";14 write(fd,buf,strlen(buf));15 fork();16 return 0;17 18 19 }

我们如果往文件中输出的话,为什么会存在下面的问题呢
在这里插入图片描述
解释:如果是输出到屏幕上的,属于行刷新,一行满了就立刻刷新到内核级缓冲区中去,而如果输出到文件中去,他是全缓冲,直到用户级缓冲区写满之后,才会写入到内核级缓冲区中去,而write是直接写到内核级缓冲区里面的,在fork之前,语言级缓冲区里面只有父进程缓冲区的内容也就是只有一遍hello fprintf ,hello printf,当fork后,由于子进程是复制父进程好多的内容,包括pcb结构,也就是说子进程的文件缓冲区和父进程的文件缓冲区指向的是同一个,如果发生写时拷贝的话,操作系统会给子进程单独搞一个内核级缓冲区,内容和父进程一样hello fprintf ,hello printf,深拷贝导致缓冲区地址不一样,但是都是一个文件的缓冲区,子进程写时拷贝后导致这个文件的文件缓冲区满了,然后就会刷新,将父进程的缓冲区,和子进程的缓冲区的内容都刷新到文件中去,write是系统调用,自然不会有语言级的缓冲区,也不会让子进程在拷贝一个新的缓冲区


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

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

相关文章

Ceph分布式存储系统以及高可用原理

Ceph分布式存储系统以及高可用原理 1. Ceph原理和架构1.1 分布式存储系统抽象1.2 Ceph基本组件 2 Ceph中的策略层2.1 CRUSH进行数据分发和定位2.2 PG(Placement Group): 集群管理的基本单元2.3 PG的代理primary OSD2.4 轻量级的集群元数据ClusterMap2.5 对PG的罗辑分组&#xf…

谷粒商城——通过接口幂等性防止重复提交订单

如果用户向后端服务提交多次相同订单的提交服务&#xff0c;那么后端应该只生成一条订单记录。 有一些操作天然是幂等的&#xff0c;如查询操作和删除操作等。 幂等性实现 1.token机制&#xff08;仅这个方法适用于订单的重复提交&#xff09; 后端先生成1个令牌将其记录在R…

通用开发技能系列:SQL基础学习

云原生学习路线导航页&#xff08;持续更新中&#xff09; 本文是 通用开发技能系列 文章&#xff0c;主要对编程通用技能 SQL基础 进行学习 1.数据库简介 1.1.数据库中的一些名称 DataBase&#xff1a;数据库 程序员只负责怎么维护存取数据&#xff0c;不管数据库是什么 DBA…

Django之关系模型的序列化

一、关系模型的序列化-多查1 1.1、模型准备 from django.db import models# Create your models here. class Classes(models.Model):name = models.CharField(max_length=20, verbose_name=班级)class Student(models.Model):SEX_CHOICES = ((1,男)), (2, 女)name = models.C…

【HTML】制作一个简单的三角形动态图形

目录 前言 开始 HTML部分 CSS部分 效果图 总结 前言 无需多言&#xff0c;本文将详细介绍一段HTML和CSS代码&#xff0c;具体内容如下&#xff1a; 开始 首先新建文件夹&#xff0c;创建两个文本文档&#xff0c;其中HTML的文件名改为[index.html]&#xff0c;CSS的文件名…

【Python的第三方库】flask

1. Flask是什么&#xff1f; 基于python的web后端开发轻量级框架&#xff1b; 基于MVT设计模式即Models,Views,Templates(html模板语言) 2.中文文档&#xff1a; https://dormousehole.readthedocs.io/en/2.1.2/index.html 3.依赖3个库&#xff1a; Jinja2 模版&#xff1…

【Unity灶台】食品加工系统模型搭建

&#x1f468;‍&#x1f4bb;个人主页&#xff1a;元宇宙-秩沅 &#x1f468;‍&#x1f4bb; hallo 欢迎 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! &#x1f468;‍&#x1f4bb; 本文由 秩沅 原创 &#x1f468;‍&#x1f4bb; 收录于专栏&#xff1a;uni…

pwn学习笔记(7)--堆相关源码

相关源码&#xff1a; 1. chunk 相关源码&#xff1a; ​ 对于用户来说&#xff0c;只需要确保malloc()函数返回的内存不会发生溢出&#xff0c;并且在不用的时候使用free() 函数将其释放&#xff0c;以后也不再做任何操作即可。而对于glibc来说’它要在用户第一次调用malloc…

4.4总结

这两天学习了线段树和树状数组&#xff0c;今晚上学长还在进行JDBC和MYSQL的教学&#xff0c;也收获到了一些东西 树状数组与完全二叉数结构上大致相同&#xff0c;但是完全二叉树每个节点只能存储单个数&#xff0c;而树状数组存储的是数组的范围。 从头结点开始为一整个数组…

Linux之实现Apache服务器监控、数据库定时备份及通过使用Shell脚本发送邮件

目录 一、Apache服务器监控 为什么要用到服务监控&#xff1f; 实现Apache服务器监控 二、数据库备份 为什么要用到数据库备份&#xff1f; 实现数据库备份 三、Shell脚本发送邮件 为什么要用使用Shell脚本发送邮件&#xff1f; 实现Shell脚本发送邮件 一、Apache服务器…

Spring声明式事务以及事务传播行为

Spring声明式事务以及事务传播行为 Spring声明式事务1.编程式事务2.使用AOP改造编程式事务3.Spring声明式事务 事务传播行为 如果对数据库事务不太熟悉&#xff0c;可以阅读上一篇博客简单回顾一下&#xff1a;MySQL事务以及并发访问隔离级别 Spring声明式事务 事务一般添加到…

VSCODE使用VSIX安装扩展

VSCode安装扩展特别慢&#xff0c;使用命令行安装告别龟速&#xff1a; code --install-extension当然&#xff0c;我这个是在WSL 的linux上安装的&#xff0c;Windows一样的。 VSCode扩展商店网页链接&#xff1a;https://marketplace.visualstudio.com/vscode

号卡极团分销管理系统 index.php SQL注入漏洞复现

0x01 产品简介 号卡极团分销管理系统,同步对接多平台,同步订单信息,支持敢探号一键上架,首页多套UI+商品下单页多套模板,订单查询支持实时物流信息、支持代理商自定义域名、泛域名绑定,内置敢探号、172平台、号氪云平台第三方接口以及号卡网同系统对接! 0x02 漏洞概述…

数字信号处理实验---FFT分析

一、题目&#xff1a; 二、实验要求&#xff1a; 1、绘制图形时&#xff0c;尽量选用已经提供的函数。 2、所有的图形&#xff0c;需要加上横坐标、纵坐标以及标题的说明。 3、将设计的程序保存为脚本文件&#xff0c;在实验报告中&#xff0c;需写出程序语句。 4、Matlab程…

ECC升级S/4HANA“沙箱模拟方案包“:更适用于升级环境复杂、体量大的客户

“作为一家业务体量大的公司&#xff0c;分支机构众多、数据复杂&#xff0c;想从ECC升级会有什么风险&#xff1f;”面对技术更新换代、公司业务不断扩展、网络安全问题的日益突出&#xff0c;将ECC升级到S/4HANA是企业的当务之急。为解决客户的顾虑&#xff0c;无论是对于历史…

51单片机入门_江协科技_19~20_OB记录的笔记

19. 串口通讯 19.1. 串口介绍&#xff1a; •串口是一种应用十分广泛的通讯接口&#xff0c;串口成本低、容易使用、通信线路简单&#xff0c;可实现两个设备的互相通信。 •单片机的串口可以使单片机与单片机、单片机与电脑、单片机与各式各样的模块互相通信&#xff0c;极大的…

设计模式总结-建造者模式

建造者模式 模式动机模式定义模式结构模式分析建造者模式实例与解析实例&#xff1a;KFC套餐 模式动机 无论是在现实世界中还是在软件系统中&#xff0c;都存在一些复杂的对象&#xff0c;它们拥有多个组成部分&#xff0c;如汽车&#xff0c;它包括车轮、方向盘、发送机等各种…

使用labelImg标注yolov5数据集并在kaggle中使用yolov5

使用labelImg标注yolov5数据集并在kaggle中使用yolov5 文章目录 前言一、labelImg标注1.1. 下载exe文件1.2. labelImg 下载&#xff08;源码&#xff09;1.3. 环境配置1.4. 使用1.4.1. 设置1.4.2. 导入图片并标注 二、在kaggle中使用2.1. 下载源码2.2. 编辑配置文件2.3. 将压缩…

[蓝桥杯 2017 国 C] 合根植物

[蓝桥杯 2017 国 C] 合根植物 题目描述 w 星球的一个种植园&#xff0c;被分成 m n m \times n mn 个小格子&#xff08;东西方向 m m m 行&#xff0c;南北方向 n n n 列&#xff09;。每个格子里种了一株合根植物。 这种植物有个特点&#xff0c;它的根可能会沿着南北…

StarRocks使用Minio备份和还原

1.安装minio Centos7安装minio-CSDN博客 minio api端口&#xff1a;9090 下文用到这个端口 必须提前创建好桶: packfdv5 名称自定义和后面对上就可以 2.创建备份仓库 格式&#xff1a; CREATE REPOSITORY <repository_name> WITH BROKER ON LOCATION "s3a:/…