Linux-- 重定向缓冲区

目录

0.接上篇文章

1.粗略的见一下这两个问题

2.理解重定向 

3.理解缓冲区 


0.接上篇文章

Linux--基础IO(文件描述符fd)-CSDN博客

1.粗略的见一下这两个问题

先来了解几个函数:

         stat()函数用于获取指定文件或符号链接的元数据。如果文件是一个符号链接,stat()将返回该符号链接本身的元数据,而不是它所指向的目标文件的元数据。

   fstat()函数用于获取已打开文件的元数据。它通常用于在文件描述符已经打开之后获取文件的元数据。

   lstat()函数与stat()函数类似,但它专门用于获取符号链接的元数据。如果指定的文件是一个符号链接,lstat()将返回该符号链接本身的元数据,而不是它所指向的目标文件的元数据。

  • fd:一个已打开的文件描述符。
  • buf:一个指向struct stat的指针,用于存储符号链接的元数据。
  • path:要检查的文件或目录的路径。

        这三个函数都使用struct stat结构来存储文件的元数据。这个结构包含了许多字段,如文件类型(普通文件、目录、符号链接等)、权限、所有者ID、组ID、大小、时间戳等。具体的字段取决于你的系统和编译器,但你可以查阅sys/stat.h头文件以获取更多详细信息。

演示:


再来看一段代码:

        我们打开文件的时候做了一个操作,colse(1)首先关闭了文件描述符 1,我们知道文件描述符1,表示的是显示器文件,而printf&&fprintf都是向显示器上打印的,现在关闭了显示器文件,意味着显示器上不会出现打印的内容。

        文件描述符1被关闭了,意味着fd1空了出来,那么log.txt将继承fd1(文件描述符分配规则;查自己的文件描述表,分配最小的没有被使用的fd),那么现在向fd1中写就是在向log.txt中写,所以我们查看到log.txt中的内容就是printf&&fprintf输出的内容,这就是对文件做重定向重定向的本质:是在内核中改变文件描述符表特定下标的内容,和上层无关!)

在这段代码中:我们还需要注意一点,fflush(stdout)刷新stdout,如果不进行此操作,log.txt中是不会有任何内容的,这是为什么呢?

原因是:在struct FILE*这个结构体中存在语言级别的缓冲区,我们在使用printf&&fprintf时,并不是直接通过文件描述符写入到内核文件缓冲区中,而是先写到语言级别的缓存区中,再由C语言通过文件描述符,刷新到内核文件缓存区当中,此时外设才能看到输出的内容,因此fflush(stdout)此时的工作是将stdout缓冲区中的内容通过文件描述符1,刷新到log.txt内核文件缓存区当中去,这时候log.txt中才能看到内容。如果没有close(fd)这一语句,那么不加刷新也没关系,进程结束之后,会自动通过fd刷新到文件中。


2.理解重定向 

先认识一个系统调用接口:dup2

  dup2 的功能是将一个已存在的文件描述符复制到另一个文件描述符,如果目标文件描述符已经打开,则先将其关闭。(本质是文件描述符下标所对应内容的拷贝)

#include <unistd.h>  int dup2(int oldfd, int newfd);

1. 标准输出重定向,由显示器打印->log.txt打印(接上面例子,我们使用dup2系统调用接口该如何做呢?)

        也就是我们没有关闭fd1,那么新打开的log.txt的fd就是3,我们使用了dup2的效果就是,把fd3的内容拷贝给了fd1,也就是说,让fd1指向了文件log.txt,所以未来向fd1里写入内容,实际上就是向log.txt中写入内容,最终只会留下fd3(oldfd)。(fd1和fd3里的地址一样l)

那么代码就应该这么写:

这样输出到显示器的内容就输出到log.txt了


3.理解缓冲区 

在Linux操作系统中,缓冲区是一个非常重要的概念,主要用于提高I/O(输入/输出)操作的效率。以下是关于Linux操作系统中缓冲区的理解:

  1. 概念:缓冲区是内存中的一块区域,用于临时存放数据。当进程需要向外部设备(如磁盘、网络等)写入数据时,它不会直接将数据写入设备,而是先将数据写入到缓冲区中。同样,当进程从外部设备读取数据时,数据也是先从设备读取到缓冲区,当缓冲区的数据到达某个值的时候,在统一的刷新到进程中。
  2. 作用
    • 减少对外部设备的直接访问次数,从而降低I/O操作的开销。
    • 允许进程进行批量数据传输,从而提高数据传输的效率。
    • 通过缓存数据,可以实现对数据的预处理和后处理,如数据压缩、加密等。
  3. 刷新策略:Linux中的缓冲区有不同的刷新策略,以适应不同的应用场景。
    • 无缓冲:数据一写入到缓冲区就立即刷新到外部设备。(eg:1.语言级的缓冲区printf/fprintf,2.系统调用fsync)
    • 行缓冲:当在输入或输出中遇到换行符(\n)时,缓冲区会刷新一次。这种策略常用于与终端设备(如显示器)的交互。
    • 全缓冲:当缓冲区满时,数据才会被刷新到外部设备。这种策略常用于写入磁盘文件等场景。
    • 特殊情况(1.进程退出,自动刷新;2强制刷新)
  4. 与文件系统的关系:在Linux文件系统中,缓冲区也起着重要的作用。当应用程序读取文件时,内核会将文件数据读入内核空间缓冲区中,然后再将数据从内核空间缓冲区复制到用户空间缓冲区中。同样地,当应用程序向文件写入数据时,数据也是先写入到用户空间缓冲区中,然后再由内核将数据从用户空间缓冲区复制到内核空间缓冲区,并最终写入到磁盘上。
  5. 缓冲区就在struct FILE*结构体中,每一个文件都有自己的缓冲区(这是在语言层面的)

补充示例

        刷新策略发生改变,看下面的两段代码:

第一段代码及它的运行结果(我们将打印到屏幕的内容重定向到文件中)

第二段代码及它的运行结果(与第一段代码不同的是,加入了一个fork函数)

问题:为什么加了fork之后,会打印两次内容,fork不是只会继承父进程下面的代码吗?为什么C语言库函数的内容打印了两次,而系统调用的只打印了一次呢?

        首先./mytest这个操作是向显示器文件打印,显示器文件的刷新策略是行缓冲,现在转为向普通文件打印,普通文件的刷新策略是全缓冲,由显示器文件转向普通文件打印,这里刷新策略就发生了改变此时printf/fprintf在执行完之后,缓冲区还没有写满(因为是全缓冲),不做刷新,最后fork的时候就出现了父子进程,fork结束后进程就直接退出了,此时父子进程都要执行刷新,所以就打印了两次内容,而系统调用接口是直接向内核级缓冲区中写的,所以不存在刷新两次的问题了。

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

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

相关文章

Android 系统省电软件分析

1、硬件耗电 主要有&#xff1a; 1、屏幕 2、CPU 3、WLAN 4、感应器 5、GPS(目前我们没有) 电量其实是目前手持设备最宝贵的资源之一&#xff0c;大多数设备都需要不断的充电来维持继续使用。不幸的是&#xff0c;对于开发者来说&#xff0c;电量优化是他们最后才会考虑的的事情…

【C++】详解STL的适配器容器之一:优先级队列 priority_queue

目录 堆算法 概述 向下调整建堆 向上调整建堆 建堆算法 仿函数 概述 使用介绍 emtpy size top push pop 模拟实现 仿函数 框架 向下调整算法 向上调整算法 pop push empty top 要理解优先级队列&#xff0c;需要有如下知识 STL容器之一的vector&#xf…

聚类分析 | 基于GA遗传算法优化kmeans聚类(Matlab)

聚类分析 | 基于GA遗传算法优化kmeans聚类&#xff08;Matlab&#xff09; 目录 聚类分析 | 基于GA遗传算法优化kmeans聚类&#xff08;Matlab&#xff09;效果一览基本介绍程序设计参考资料 效果一览 基本介绍 GA-kmeans聚类算法&#xff0c;通过GA遗传算法优化kmeans聚类&…

【python】模块与包

Python中的模块和包是组织和管理代码的重要工具。通过模块和包&#xff0c;你可以更好地管理和重用你的代码&#xff0c;使得代码更加模块化和可维护。 目录 前言 正文 一、模块 1、模块的分类 1&#xff09;内置模块 python解释器中默认拥有的模块可以直接使用&#xff08;…

用户需求甄别和筛选的6大标准

产品经理日常经常接收到大量的需求&#xff0c;并不是所有的需求都需要开发&#xff0c;需要进行甄别和筛选&#xff0c;这样有利于确保项目的成功、优化资源利用以及提高产品质量。 那么针对这些用户需求进行甄别或筛选的评判标准是什么&#xff1f;需求筛选可以说是初步的需求…

代码随想录-算法训练营day31【贪心算法01:理论基础、分发饼干、摆动序列、最大子序和】

代码随想录-035期-算法训练营【博客笔记汇总表】-CSDN博客 第八章 贪心算法 part01● 理论基础 ● 455.分发饼干 ● 376. 摆动序列 ● 53. 最大子序和 贪心算法其实就是没有什么规律可言&#xff0c;所以大家了解贪心算法 就了解它没有规律的本质就够了。 不用花心思去研究其…

C++牛客周赛题目分享(2)小红叕战小紫,小红的数组移动,小红的素数合并,小红的子序列求和

目录 ​编辑 1.前言 2.四道题目 1.小红叕战小紫 1.题目描述 2.输入描述 3.输出描述 4.示例 5.题解与思路 2.小红的数组移动 1.题目描述 2.输入描述 3.输出描述 4.示例 5.题解与思路 3.小红的素数合并 1.题目描述 2.输入描述 3.输出描述 4.示例 5.题解与思…

云原生新手和开源教育分论坛 01-Kubernetes 社区:从新手到影响者

2024年04月20日 上海KCD & Shanghai&#xff1a;https://community.cncf.io/events/details/cncf-kcd-shanghai-presents-kcd-shanghai-2024/视频观看&#xff1a;https://www.bilibili.com/video/BV1nD421T786/?spm_id_from333.999.0.0&vd_sourceae7b192be069682aabc…

【FreeRTOS 快速入门】-- 1、STM32工程移植FreeRTOS

目录 一、新建STM32工程 为了示范完整的移植过程&#xff0c;我们从0开始&#xff0c;新建一个标准的STM32点灯工程。 &#xff08;本篇以CubeMX作示范&#xff0c;CubeIDE操作近同&#xff0c;可作对比参考&#xff09; 1、新建工程 选择 芯片型号 新建工程 2、搜索芯片型号…

24年做抖音小店,你还停留在数据?别人都已经开始注重利润了

大家好&#xff0c;我是电商笨笨熊 一件事情持续做&#xff0c;一个项目持续深耕&#xff0c;意义到底是什么&#xff1f; 这句话我常常说&#xff0c;但很多人似乎走偏了实际意义&#xff1b; 尤其对于新手来说&#xff0c;做抖音小店总是向往某某老玩家多么牛的数据&#…

程序员健康指南:运动,让代码更流畅

程序员健康指南&#xff1a;运动&#xff0c;让代码更流畅 程序员&#xff0c;一个与电脑相伴的群体&#xff0c;长时间的久坐和高强度的脑力劳动是他们的日常。然而&#xff0c;久坐不仅影响体态&#xff0c;更对心脏健康构成威胁。根据《欧洲心脏杂志》的研究&#xff0c;中…

【PPT技巧】ppt文件打开就是只读模式,如何改为可编辑模式?

PPT文档打开是只读模式&#xff0c;如何改成可编辑文档呢&#xff1f;这需要分几种情况来说&#xff0c;所以今天将介绍几种方法帮助PPT只读文档改为可编辑文档。 方法一&#xff1a; 我们可以先查看一下文件属性&#xff0c;属性中有只读属性&#xff0c;当我们打开文档之后带…

C++入门——引用(2)

前言 上一节我们开始学习了C&#xff0c;并且对C有了初步的了解&#xff0c;这一节我们继续学习C的基础&#xff0c;那么废话不多说&#xff0c;我们正式进入今天的学习 C中的引用 1.1引用的概念 引用不是新定义一个变量&#xff0c;而是给已存在变量取了一个别名&#xff0…

uniapp小程序:大盒子包裹小盒子但是都有点击事件该如何区分?

在开发过程中我们会遇到这种情况&#xff0c;一个大盒子中包裹这一个小盒子&#xff0c;两个盒子都有点击事件&#xff0c;例如&#xff1a; 这个时候如果点击评价有可能会点击到它所在的大盒子&#xff0c;如果使用css中的z-index设置层级的话如果页面的盒子多的话会混乱&…

Spring解决泛型擦除的思路不错,现在它是我的了。

你好呀&#xff0c;我是浮生。 Spring 的事件监听机制&#xff0c;不知道你有没有用过&#xff0c;实际开发过程中用来进行代码解耦简直不要太爽。 但是我最近碰到了一个涉及到泛型的场景&#xff0c;常规套路下&#xff0c;在这个场景中使用该机制看起来会很傻&#xff0c;但…

15、FreeRTOS 软件定时器

文章目录 一、什么是定时器?1.1 定时器的理解1.2 软件定时器的特性 二、 软件定时器的上下文2.1 守护任务2.2 守护任务的调度2.3 回调函数 三、软件定时器的函数3.1 创建3.2 删除3.3 启动/停止3.5 修改周期3.6 定时器ID 四、案例4.1 一般使用4.2 消除抖动 一、什么是定时器? …

Midjourney Imagine API 申请及使用

Midjourney Imagine API 申请及使用 申请流程 要使用 Midjourney Imagine API&#xff0c;首先可以到 Midjourney Imagine API 页面点击「Acquire」按钮&#xff0c;获取请求所需要的凭证&#xff1a; 如果你尚未登录或注册&#xff0c;会自动跳转到登录页面邀请您来注册和登…

语音转文字服务的调用接口

语音转文字&#xff08;Speech-to-Text&#xff0c;STT&#xff09;技术允许将口语化的语音转换成书面文字。以下是一些提供语音转文字服务的调用接口及其特点。北京木奇移动技术有限公司&#xff0c;专业的软件外包开发公司&#xff0c;欢迎交流合作。 1.讯飞开放平台语音转写…

[猫头虎分享21天微信小程序基础入门教程]第1天:微信小程序概述与开发环境搭建教程

第1天&#xff1a;微信小程序概述与开发环境搭建 &#x1f63a; 文章目录 第1天&#xff1a;微信小程序概述与开发环境搭建 &#x1f63a;自我介绍微信小程序概述特点 开发环境搭建步骤1: 注册微信小程序账号步骤2: 安装开发者工具步骤3: 熟悉开发者工具界面 今日学习总结小测试…

炒股开户佣金最低万1和万0.854,融资融券现在利率最低4.0%~5%

​​炒股开户佣金一般是万1和万0.854&#xff0c;万0.854有一定的资金量要求&#xff0c;高于万1的是可以申请降低的。 开户万1佣金和万0.854佣金只需要联系证券公司客户经理协商就行。 开户流程&#xff1a; 1、向客户经理索要开户链接或者扫描二维码、进入申请页面&#x…