Linux操作系统——重定向与缓冲区

news2024/9/26 5:20:28

1.理解一下struct file内核对象

上一篇文章(文件详解)我们一直在谈,一个文件要被访问就必须要先被打开,打开之前就必须要先把文件加载到内存,同时呢我们的操作系统为了管理文件也会为我们的文件创建相对应的struct file对象,那么这个struct file对象里面应该有什么?

其实struct file里面最核心的两个:一个叫做内容,另一个叫做属性。

因为我们前面说了文件= 内容+属性。所以一个文件被打开之后最重要的要么是内容,要么是属性。

如果我们要读一个文件,那么读文件一定是由进程来读的,其中进程的PCB中包含了一个文件描述符表指针指向struct file * fd_array[]数组的一个指针,正常情况下标准输入,标准输出,标准错误三个流是默认被打开的,也就是对应着文件描述符0,1,2,所以新打开的文件一般是把新打开创建的struct file的地址填到文件描述符为3的空间里,然后将该文件描述符作为返回值传递给上层,上层拿到了文件描述符为3的文件就可以对该文件进行一系列操作了。如果我们要对文件进行读数据,首先要将文件加载至内存,如果要对文件进行写数据时我们不能在磁盘中对文件进行写入,而是要把文件加载到缓冲区(内存空间)才能进行写入操作。所以说无论读写都要先把文件加载到文件缓冲区中!

那么我们在应用层进行数据的读写本质是什么呢?其实本质是将内核缓冲区中的数据进行来回拷贝!

下面我们看一看Linux内核源代码中关于文件的结构体字段的描述

2.文件描述符fd的分配规则

下面我们先看一下以写的方式打开文件如果不存在就创建文件的方式进行代码测试:

运行后:

既然我们说默认文件描述符为0,1,2的文件流默认是打开的,那么我们直接使用文件描述符为0的文件对其进行操作即可验证这一说法,然后改写代码为:

运行之后:

既然我们可以对标准输入进行读,那么自然也可以从标准输出进行写操作,下面我们将代码修改:

运行后:

读了abcdefg,同时写入了abcdefg.

进程默认已经打开了0,1,2,我们可以直接使用0,1,2进行数据访问!

下面我们在进行一些测试:

我直接把文件描述符为0的标准输入给关了

运行之后:

发现我们以写的方式打开的新的文件的文件描述符不再是3了,而是变成了0,一个该现象并不足以说明问题,下面我们把2号标准错误流给改了,看是否打开的新文件的文件描述符会发生变化。

运行结果:

我们发现果然,文件描述符变成了2,这说明了什么问题呢?

当我们打开一个新的文件时,会从文件描述符表中从上往下扫描,寻找文件描述符最小且没有被使用的文件描述符分配为为新的文件的文件描述符。

那么下面我们把文件描述符为1的标准输出流给关了之后会发生什么现象呢?

运行之后:

我们发现什么都没有???原因就在于我们原本printf是要将内容打印到显示上的,但是我们在代码中已经把文件描述符为1的标准输出流给关闭了,所以没有打印出来。

如果我们再把代码改成这样呢?

然后运行之后,再查看一下log.txt文件中的内容:

怎么我们要打印的内容在log.txt文件里面去了?

其实很容易理解,根据我们上面的结论,文件描述符为1的标准输出流关闭了,所以log.txt打开时会被分配最小的没有被使用的文件描述符,也就是1,所以当前情况下log.txt的文件描述符为1,而这些内容会写到log.txt里面原因就在于这个过程叫做输出重定向

3.重定向

printf只认stdout,而stdout只认_fileno=1也就是文件描述符为1所指向的文件,如果文件描述符为1指向的是显示器那就往显示器上打,如果文件描述符为1指向的是log.txt文件,那就往log.txt上打,所以说重定向的本质,其实就是修改特定文件fd的下表中的内容(也就是打开文件的地址)。

下面我们再使用一个与printf比较相似的fprintf来测试:

先看一下fprintf的手册:

编写如下代码:

运行之后:

下面我们把打开方式改一下:

运行之后:

所以我们就很容易的实现了追加重定向,每次运行都是在log.txt后面进行追加。

下面我们再测试一个输入重定向:

查看一下fread的相关手册

修改代码为如下:

运行结果:

我们发现原本应该要从键盘上读取数据,最后是从log.txt的文件上进行读取的。

所以上面就说明了,上层fd不变,底层fd指向的内容在改变。

关于上述的重定向我们感觉太麻烦了,因为它还需要我们关闭相对应文件描述符指向的文件,有没有一种方法是直接把新打开的文件的地址拷贝到对应文件描述符的内容里面去完成重定向呢?也就是通过文件描述符级别的数组内容的拷贝!

答案是有的,一下就是那个接口:

这个接口的用法是将oldfd的内容拷贝到,newfd上,也就是最后两处的文件描述符都是指向oldfd所指向的内容,而这会导致两个文件描述符如何关闭的问题,其实这个问题是文件结构体中会存在一个引用计数,也就是有几个指针指向该文件,如果有多个指针就对计数那个字段进行数量控制,如果有一个指向该文件的文件描述符关闭了,那么该字段就减减,直到减到0才关闭。下面我们以输出重定向为例来测试一下dup2这个接口:

运行结果:

这就叫做重定向。

4.缓冲区

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

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

相关文章

C语言从入门到实战——结构体与位段

结构体与位段 前言一、结构体类型的声明1.1 结构体1.1.1 结构的声明1.1.2 结构体变量的创建和初始化 1.2 结构的特殊声明1.3 结构的自引用 二、 结构体内存对齐2.1 对齐规则2.2 为什么存在内存对齐2.3 修改默认对齐数 三、结构体传参四、 结构体实现位段4.1 什么是位段4.2 位段…

视频剪辑实例:探索画中画视频剪辑,创意无限可能,批量制作视频

随着社交媒体和视频平台的迅速发展,视频剪辑,作为视频创作的核心环节,对于呈现内容、传达情感和提升体验具有至关重要的作用。现在来看云炫AI智剪的视频剪辑实例,如何批量制作视频,提升工作效率。 画中画视频合并成功…

国产麒麟系统开机没有网络需要点一下这个设置

问题描述: 一台国产电脑网线连接正常,打开网页后显示无法访问,那么是什么原因无法上网呢?下面就告诉你一个小方法去解决一下这个问题; 检查故障: 检测交换机、网线、水晶头全都正常,同房间摆放的…

荣耀开发者大会 2023·一张图读懂服务分发分论坛

荣耀智慧服务,高效连接开发者与用户,构建主动服务全新体验! 2023年荣耀智慧服务总数已突破25000,帮助众多开发者提升业务增长~ 今年将会开放更多生态场景,配合多元服务分发,从应用到场景,从用…

闪存的基础知识1-Vt的定义

系列文章目录 本次系列文章主要分享与存储相关的知识 文章目录 目录 系列文章目录 前言 一、mos管 阈值电压是什么? 二、详细分析 1.通俗理解 2.读入数据 总结 前言 阈值电压(Vt) 阈值电压(Vt或Vth)的概念是从MOS管来的。 一、mos管 阈值电压是什么? …

element+vue 之图片放大器

1.安装插件 npm install vue-photo-zoom-pro2.main.js导入 // 放大镜 import VuePhotoZoomPro from vue-photo-zoom-pro Vue.use(VuePhotoZoomPro)3.页面使用 <vue-photo-zoom-pro:url"imgUrl":out-zoomer"true":scale"2"style"width:…

AI模型理解误区:微调垂直行业-VS-企业专属知识库或AI助理

概述 企业定制私有化大模型的区别&#xff0c;分为训练大模型和调用大模型两种方向&#xff0c;以及企业自己的智能客服的实现方法。 - 企业定制的私有化大模型与一般的大模型不同&#xff0c;需要高成本训练。- 企业可以选择调用已经训练好的大模型来应用。- 企业可以使用向量…

为什么建筑工程行业要十分重视主数据管理?

业务背景 主数据管理是数字化技术不可或缺的一部分。 建筑行业数字化转型中&#xff0c;跨部门协作是非常重要的。主数据管理能够提供一个统一的数据平台&#xff0c;方便各个部门数据共享和交流&#xff0c;也可以实现人力、物资、设备等各种资源的集中管理和优化配置。 此外…

[element-ui] 级联选择器el-cascader不触发change事件

el-cascader 使用官网的数据是可以的 官网数据中最后一级没有children // 删除最后一级的children changeKey(arr) {for (var i0; i<arr.length; i) {if (arr[i].children.length) {this.changeKey(arr[i].children)} else {delete arr[i].children}} ]就可以了 参考&…

浅谈专项测试之弱网络测试

一&#xff0e;弱网络测试背景 移动端产品的使用并非完全都是在流畅的wifi环境&#xff0c;大部分用户主要使用4G,3G,2G等网络&#xff0c;另外因为移动端产品使用的场景多变&#xff0c;如进公交&#xff0c;上地铁&#xff0c;坐电梯&#xff0c;使得弱网测试显得尤为重要。考…

基于springboot数码论坛系统源码和论文

网络的广泛应用给生活带来了十分的便利。所以把数码论坛与现在网络相结合&#xff0c;利用java技术建设数码论坛系统&#xff0c;实现数码论坛的信息化。则对于进一步提高数码论坛发展&#xff0c;丰富数码论坛经验能起到不少的促进作用。 数码论坛系统能够通过互联网得到广泛…

大语言模型系列-总述

大语言模型发展史 研究人员发现&#xff0c;扩展预训练模型&#xff08;Pre-training Language Model&#xff0c;PLM&#xff09;&#xff0c;例如扩展模型大小或数据大小&#xff0c;通常会提高下游任务的模型性能&#xff0c;模型大小从几十亿&#xff08;1 B 10亿&#x…

细说JavaScript对象(JavaScript对象详解)

在JavaScript中对象作为数据类型之一&#xff0c;它的数据结构区别于其余5中数据类型&#xff0c;从数据结构角度看对象就是数据值的几个&#xff0c;其书就结构就是若干组名值对&#xff0c;类似于其他语言中的哈希、散列 关联数组等&#xff0c;但对象在JavaScript中不仅仅扮…

【MySQL高级】——InnoDB数据存储结构

1. 数据库的存储结构&#xff1a;页 <1> 磁盘与内存交互的基本单位&#xff1a;页 <2> 页结构概述 <3> 页的大小 <4> 页的上层结构 2. 页的内部结构 <1> 页的分类 <2> 页的结构 <3> File Header&#xff08;文件头&#xff09; 1.…

AUTO SEG-LOSS SEARCHING METRIC SURROGATES FOR SEMANTIC SEGMENTATION

AUTO SEG-LOSS: 搜索度量替代语义分割 论文链接&#xff1a;https://arxiv.org/abs/2010.07930 项目链接&#xff1a;https://github.com/fundamentalvision/Auto-Seg-Loss ABSTRACT 设计合适的损失函数是训练深度网络的关键。特别是在语义分割领域&#xff0c;针对不同的场…

Nginx安装http2和ssl模块

Nginx安装http2和ssl模块 Nginx在执行默认安装命令的时候&#xff0c;并不会编译启用ngx_http_v2_module模块。故在修改Nginx配置文件启用http2.0协议的时候会报错。 一.检查Nginx安装了哪些模块 #进入Nginx的安装目录 cd /usr/local/nginx #执行命令查看安装了哪些模块 ./sbi…

腾讯云服务器定价_云服务器价格_云服务器计费模式

腾讯云服务器租用价格表&#xff1a;轻量应用服务器2核2G3M价格62元一年、2核2G4M价格118元一年&#xff0c;540元三年、2核4G5M带宽218元一年&#xff0c;2核4G5M带宽756元三年、轻量4核8G12M服务器446元一年、646元15个月&#xff0c;云服务器CVM S5实例2核2G配置280.8元一年…

java基本类型与包装类型之间的关系

JAVA基本类型和包装类型 前言 Java语言中的数据类型分为基本数据类型和引用类型&#xff0c;而我们进行Java开发的时候都听说过基本数据类型和包装类型&#xff0c;今天我们就来详细聊一聊Java中的基本数据类型和包装类型之间的区别。 基本数据类型 Java中的基本数据类型一共有…

2024腾讯云服务器购买指南一步步全流程攻略(超详细)

腾讯云服务器购买流程很简单&#xff0c;有两种购买方式&#xff0c;直接在官方活动上购买比较划算&#xff0c;在云服务器CVM或轻量应用服务器页面自定义购买价格比较贵&#xff0c;但是自定义购买云服务器CPU内存带宽配置选择范围广&#xff0c;活动上购买只能选择固定的活动…

运筹说 第80期 | 最小费用最大流问题

前面我们学习了图与网络分析的基础知识及经典问题&#xff0c;大家是否已经学会了呢&#xff1f;接下来小编和大家学习最后一个经典问题——最小费用最大流问题。 最小费用最大流问题是经济学和管理学中的一类典型问题。在一个网络中每段路径都有“容量”和“费用”两个限制的…