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结束后进程就直接退出了,此时父子进程都要执行刷新,所以就打印了两次内容,而系统调用接口是直接向内核级缓冲区中写的,所以不存在刷新两次的问题了。

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

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

相关文章

【多电压流程 Multivoltage Flow】- 5.特定工具使用建议(6.Formality)

使用Formality进行形式验证 Formality支持具有低功耗特性的功能等效性检查,如时钟门控、多阈值电压(multiple-Vt)、多电压供电、电源门控以及动态电压和频率缩放。Formality能够识别低功耗单元,例如隔离单元、电平转换器、始终开启单元、保持寄存器和电源门。 Formality支持…

MQTT 5.0 报文解析 04:PINGREQ 与 PINGRESP

欢迎阅读 MQTT 5.0 报文系列 的第四篇文章。在上一篇中&#xff0c;我们已经介绍了 MQTT 5.0 中的 SUBSCRIBE 报文和 UNSUBSCRIBE 报文。现在&#xff0c;我们将介绍用于维持连接的控制报文&#xff1a;PINGREQ 和 PINGRESP。 除了用于连接、发布和订阅的控制报文&#xff0c;…

抖音上有可以长久赚钱的副业吗?当然有,只有它最稳定长久!

大家好&#xff0c;我是电商糖果 现在有很多年轻人在大城市上班&#xff0c;发现辛辛苦苦一年也赚不到多少钱。 如果说自己有了房贷&#xff0c;车贷&#xff0c;那更是一点儿不敢歇。 为了可以有更多的收入&#xff0c;年轻人都希望可以靠着下班时间&#xff0c;找一个可以…

visual sudio使用-创建空项目-创建cpp文件

新建空项目 新建cpp文件 #include <iostream> using namespace std;int main() {cout << "hello vs" << endl;cout << "hello c" << "\n";cout << "hello first day\n"; }

如何在群晖NAS中开启FTP并实现使用公网地址远程访问传输文件

文章目录 1. 群晖安装Cpolar2. 创建FTP公网地址3. 开启群晖FTP服务4. 群晖FTP远程连接5. 固定FTP公网地址6. 固定FTP地址连接 本文主要介绍如何在群晖NAS中开启FTP服务并结合cpolar内网穿透工具&#xff0c;实现使用固定公网地址远程访问群晖FTP服务实现文件上传下载。 Cpolar内…

关于SQL

数据库简介&#xff1a; 数据库分类 关系型数据库模型&#xff1a; 优点&#xff1a;易于维护&#xff0c;可以实现复杂的查询 缺点&#xff1a;海量数据 读取写入性能差&#xff0c;高并发下数据库的io是瓶颈 是把复杂的数据结构归结为简单的二元关系&#xff08;即二维表…

【数据结构】有关栈和队列相互转换问题

文章目录 用队列实现栈思路实现 用栈实现队列思路实现 用队列实现栈 Leetcode-225 用队列实现栈 思路 建立队列的基本结构并实现队列的基本操作 这部分这里就不多说了&#xff0c;需要的可以看笔者的另一篇博客 【数据结构】队列详解(Queue) 就简单带过一下需要实现的功能 …

分布式光伏管理系统的意义与核心技术

分布式光伏管理系统遵循安全可靠、经济合理原则&#xff0c;满足电力系统自动化总体规划要求&#xff0c;且充分考虑光伏发电的因素&#xff0c;对分布式光伏发电、用电进行集中监控、统一调度、统一运维。为用户提供运维服务&#xff0c;实现能源互联&#xff0c;信息互通&…

从使用教程、实现原理、差异对比全方面带你玩转业务系统中高频使用的过滤器与拦截器

1.概述 在Java Web开发中&#xff0c;**过滤器&#xff08;Filter&#xff09;和拦截器&#xff08;Interceptor&#xff09;**是两种常见的组件&#xff0c;用于在请求到达目标资源之前或之后执行一些操作&#xff0c;如日志记录、权限控制、字符编码处理等。虽然它们的作用有…

【Qt】demo示例--通过定时器实现时间刷新

【Qt】demo示例--通过定时器实现时间刷新 1.背景2.代码3.运行 1.背景 Qt Creator版本&#xff1a;4.2.0 &#xff0c;如下图&#xff1a; 即安装qt-opensource-windows-x86-msvc2013_64-5.7.1.exe 后自带得Qt编程IDE&#xff1b; 2.代码 项目结构如下&#xff1a; mydial…

Navicat Premium数据库新建函数报错问题

1.问题产生原因&#xff1a; (1)可能是软件 Navicat Premium 的版本不一样 (2)可能是与某些字符集不一样 2.找出解决办法&#xff1a; (1)参考对照系统自带sys数据库表的函数找出的区别&#xff08;后面遇到同样问题可以这样排查&#xff09; (2)不加 DETERMINISTIC 声明&a…

js图片回显的方法

直接上代码&#xff1a; <!DOCTYPE html> <html><head><meta charset"utf-8"><title></title></head><body>// HTML部分<input type"file" id"fileInput"><button onclick"show…

Nginx内网环境开启https

文章目录 前言一、open-ssl1. 验证2. 安装3.生成ssl证书 一、nginx1. 验证支持模块2. 安装必要模块2.1 重新编译nginx2.2 替换原文件 3. 配置https 总结 前言 nginx开启https前提&#xff1a; 服务器支持open-sslnginx 包含--with-http_ssl_module --with-stream --with-stre…

融知财经:期货和现货的区别是什么?哪个风险大?

期货和现货在交易对象等方面存在明显的区别。期货交易是一种衍生金融工具&#xff0c;主要用于价格发现、风险管理和投机&#xff0c;而现货交易则是商品和服务的实际买卖。在选择进行期货交易还是现货交易时&#xff0c;投资者需要根据自己的需求和市场情况来决定。 期货和现货…

In Context Learning(ICL)个人记录

In Context Learning&#xff08;ICL&#xff09;简介 In Context Learning&#xff08;ICL&#xff09;的关键思想是从类比中学习。上图给出了一个描述语言模型如何使用 ICL 进行决策的例子。首先&#xff0c;ICL 需要一些示例来形成一个演示上下文。这些示例通常是用自然语言…

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

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

华东政法大学公布2024《负面清单期刊目录》,附目录

近日&#xff0c;华东政法大学公布2024《负面清单期刊目录》&#xff0c;包括《齐齐哈尔大学学报(哲学社会科学版)》《景德镇学院学报(社科)》《九江学院学报(社科)》《北京印刷学院学报》《江西电力职业技术学院学报》《中国多媒体与网络教学学报》《吉林省教育学院学报》《开…

pyqt动画效果放大与缩小

pyqt动画效果放大与缩小 QPropertyAnimation介绍放大与缩小效果代码 QPropertyAnimation介绍 QPropertyAnimation 是 PyQt中的一个类&#xff0c;它用于对 Qt 对象的属性进行动画处理。通过使用 QPropertyAnimation&#xff0c;你可以平滑地改变一个对象的属性值&#xff0c;例…

【新手入门】Github与Git使用教程

Github与Git 一、Github基础教程 1.1 基本操作 点击代码文件可以直接查看文件的内容&#xff0c;支持在线修改文件&#xff0c;只需要点击(文件内容)右上角的编辑按钮即可进行编辑。 README.md一般介绍项目的功能&#xff0c;用法&#xff0c;注意事项&#xff1b;有时还有…

二、安装、使用Grafana

目录 一、安装Grafana 二、使用grafana 一、安装Grafana 官网&#xff1a;https://grafana.com/ 账号&#xff1a;admin 密码&#xff1a;xxxxxx [rootrabbitmq_2 prometheus]# [rootrabbitmq_2 prometheus]# wget https://dl.grafana.com/enterprise/release/grafana-enter…