【Linux】访问文件的本质|文件描述符|文件重定向

文章目录

  • 文件的结构
  • 文件描述符
    • 标准输入输出
    • 文件描述符的规则
  • 文件重定向
    • 输出重定向(对应符号'>')
      • echo的输出重定向
    • 输入重定向(对应符号'<')
    • 追加重定向(对应符号‘>>’)
    • 实现文件重定向的函数dup2()
      • 参数
      • 测试

前言:本文探讨的是操作系统中的文件本质,探讨“打开的文件”,与语言无关。

观察我们平时写的C语言文件操作的函数,例如:

FILE* fp = fopen("log.txt", "w");

可以发现返回值的类型是FILE* ,那么这个FILE*到底是什么?

FILE* 是C库自己封装的结构题FILE的指针

系统调用接口中,我们会使用下面的函数:

int fd = open("log.txt", O_WRONLY|O_CREAT|O_TRUNC);

可以发现返回值的类型是int,返回的内容是fd。这个fd我们称为文件描述符。

文件的结构

关于文件的结构,可以对比进程的结构,都i是差不多的。
当操作系统想管理文件的时候,需要做的是什么呢?
先把文件描述出来,然后再对大量的文件进行组织 — > 先描述再组织

对于文件,有很多属性,那我们就需要对每个属性进行封装,需要一个task_struct结构体对这些属性进行封装。

在task_struct中,有struct files_struct 结构体,这个结构体就是管理文件的。每创建一个文件,就在files_struct中进行一些操作(具体操作后面详细说明)。

那么,在task_struct中,想要对files_struct中进行操作,就需要有files_struct的指针,也就是 struct files_struct *f,这个指针操作files_struct。

在files_struct中有很多struct_file对象,每打开一个文件,就创建一个struct_file对象,在这个struct_file中存储的是什么呢?就是文件的各种属性:在磁盘的什么位置,基本属性,权限,大小,读写位置等,最重要的是struct_file * next指针,正是因为有了这个指针,就导致所有分离的文件通过链表的形式连接起来了。

现在我们已经知道struct_file对象通过链表连接起来了,就相当于一串一样,此时,在struct_file的上级 file_struct中是不是存了管理struct_file的指针。此时,在file_struct中创建一个数组,数组的内容就是存放指针,所以该数组是指针数组。数组的下标,我们就称为文件描述符,就是fd这个数组我们就叫文件描述符表。

在这里插入图片描述
这些都可以在操作系统的源码中看到

文件描述符

标准输入输出

在这里插入图片描述
运行结果:
在这里插入图片描述
根据结果可以发现文件描述符fd = 3。
为什么是3? 0,1,2去哪里了?
在这里插入图片描述
0号文件 —— stdin —— 标准输入
1号文件 —— stdout —— 标准输出
2号文件 —— stderr —— 标准错误

如何验证?

在这里插入图片描述
在这里插入图片描述
从这里可以看出0号文件确实就是stdin。

文件描述符的规则

在这里插入图片描述
上述代码中 close(1)表示的是将1号文件关闭。
接着,打开了一个叫做log.txt的文件。
将msg中内容写入到1号文件中。 1号文件是标准输出。

观察输出结果:
在这里插入图片描述
为什么我们明明是向1号文件中写入,不写入到标准输出(显示器)上,反而出现在了log.txt的文件中?

因为我们刚刚做了一个操作,是close(1),关闭1号文件。还记得我们之前有一个示例代码中打开文件,fd = 3,那时是因为0,1,2文件都被占用了,所以是3号文件。

现在1号文件的位置被腾出来了,所以新打开的文件就从前往后扫描,哪里空闲,就直接写入就行了。

这就是为什么向1号文件写入,却写进了log.txt中原因了。因为此时log.txt的文件的fd = 1.

本来如果不关闭1号文件,应该是如下图的结构
在这里插入图片描述
在关闭之后就变成下面这样了。
在这里插入图片描述

文件重定向

文件重定向有输出重定向,输入重定向,追加重定向,下面一一讲解。

输出重定向(对应符号’>')

其实上面的例子就是输出重定向。
在这里插入图片描述
所谓输出重定向,就是将本该输出到x的内容输出到y中。
操作:断开fd = i与文件x的链接,将fd = i 和 文件y重新建立连接。
上面的例子就是:本来应该输出到stdout中,但是由于将fd = 1和stdout的链接断了,并将log.txt链入到fd = 1中,所以输出就到了log.txt中。

echo的输出重定向

在这里插入图片描述
本来echo是向显示器中打印内容,现在:
将echo和stdout的链接断开,并重新建立echo和log.txt的链接
从而,可以将echo的内容打印到log.txt中。

输入重定向(对应符号’<')

同输出重定向一样,输入重定向就是将fd = 0 和stdin的链接断了,然后重新链接。
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
上面的代码就是将stdin中的内容输入到buffer中。
我们将fd = 0和stdin的链接关了,并打开了一个文件test.txt,此时test.txt的fd = 0.
此时text.txt就是stdin
所以代码中将stdin写入到buffer中,其实是将fd = 0的文件的内容写入到buffer中,此时fd = 0的文件是test.txt,所以就是将test.txt的内容写入到buffer中。

追加重定向(对应符号‘>>’)

追加重定向和输出重定向的区别就是:
输出重定向会覆盖之前写的内容
追加重定向是在原本的内容之上进行追加,不会覆盖
在这里插入图片描述

结果:
在这里插入图片描述
最前面的字母是原来的,后面的汉字是追加的。

实现文件重定向的函数dup2()

dup2是实现文件重定向的函数,有了这个函数我们就不需要自己操作close(fd)再重新连接。

dup2的函数描述
在这里插入图片描述

参数

int dup2(int oldfd, int newfd)

可以看到有oldfd和newfd,该怎么理解?
oldfd就是我们准备重定向到的文件,在前面的例子中就是test.txt, newfd就是我们准备断开链接的文件,在前面的例子中就是1或者 0

函数解释:简单来说就是将oldfd的地址拷贝一份,让newfd指向oldfd的地址。

测试

在这里插入图片描述
测试结果:
在这里插入图片描述

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

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

相关文章

could not publish server configuration for tomcat at localhost

1&#xff0c;报错信息如图&#xff1a; 2&#xff0c;找到servers双击&#xff0c;选择Modules&#xff0c;如果有两个webModules ,remove一个&#xff0c; 3&#xff0c;如果重启还是报错&#xff0c;干脆两个都remove&#xff0c;双击tomcat服务add And Remove重新添加

springboot/ssm酒店客房管理系统Java在线酒店预约预定平台web

springboot/ssm酒店客房管理系统Java在线酒店预约预定平台web 基于springboot(可改ssm)vue项目 开发语言&#xff1a;Java 框架&#xff1a;springboot/可改ssm vue JDK版本&#xff1a;JDK1.8&#xff08;或11&#xff09; 服务器&#xff1a;tomcat 数据库&#xff1a;…

【Python】深度学习基础知识——梯度下降详解和示例

尽管梯度下降&#xff08;gradient descent&#xff09;很少直接用于深度学习&#xff0c;但它是随机梯度下降算法的基础&#xff0c;也是很多问题的来源&#xff0c;如由于学习率过大&#xff0c;优化问题可能会发散&#xff0c;这种现象早已在梯度下降中出现。本文通过原理和…

Docker知识点总结

二、Docker基本命令&#xff1a; Docker支持CentOs 6 及以后的版本; CentOs7系统可以直接通过yum进行安装&#xff0c;安装前可以 1、查看一下系统是否已经安装了Docker: yum list installed | grep docker 2、安装docker&#xff1a; yum install docker -y -y 表示自动确认…

flutter旋转动画,算法题+JVM+自定义View

在很多的博客或者书上&#xff0c;说有三种&#xff0c;除了上述的两种以外&#xff0c;还有一种是实现Callable接口。但是这种并不是&#xff0c;因为&#xff0c;我们检查JDK中Thread的源码&#xff0c;看它的注释&#xff1a; There are two ways to create a new thread o…

Linux操作系统的vim常用命令和vim 键盘图

在vi编辑器的命令模式下&#xff0c;命令的组成格式是&#xff1a;nnc。其中&#xff0c;字符c是命令&#xff0c;nn是整数值&#xff0c;它表示该命令将重复执行nn次&#xff0c;如果不给出重复次数的nn值&#xff0c;则命令将只执行一次。例如&#xff0c;在命令模式下按j键表…

Dockerfile的艺术:构建高效容器镜像的指令详解与实战指南

在容器化技术风靡全球的今天&#xff0c;Dockerfile作为构建 Docker 镜像的蓝图&#xff0c;其编写技巧与理解深度直接影响着应用部署的效率与稳定性。本文将深入剖析Dockerfile中的核心指令&#xff0c;以实战角度为您呈现一份详尽的解读与操作指南&#xff0c;并在文末抛出一…

docker通过dockerfile安装sftp教程

自制sftp镜像 Dockerfile构建镜像运行sftp容器sftp测试 Dockerfile # 使用基础镜像 FROM ubuntu:22.04# 安装 OpenSSH 服务器和 SFTP 所需的工具 RUN apt-get update && \apt-get install -y openssh-server && \mkdir /var/run/sshd # && apt-get…

mysql8 MGR集群部署

服务器环境 系统主机名IPCentOS 7.9mgr-node01192.168.200.31CentOS 7.9mgr-node02192.168.200.32CentOS 7.9mgr-node03192.168.200.33 mysql8安装 tar zxvf mysql-8.0.19-1.el7.x86_64.rpm-bundle.tar.gzrpm -e --nodeps mariadb-libs-5.5.68-1.el7.x86_64rpm -ivh mysql-c…

Fuyu-8B A Multimodal Architecture for AI Agents

Fuyu-8B: A Multimodal Architecture for AI Agents Blog: https://www.adept.ai/blog/fuyu-8b TL; DR&#xff1a;无视觉编码器和 adapter&#xff0c;纯解码器结构的多模态大模型。 Adept 是一家做 Copilot 创业的公司&#xff0c;要想高效地帮助用户&#xff0c;必须要准确…

【Linux网络】再谈 “协议“

目录 再谈 "协议" 结构化数据的传输 序列化和反序列化 网络版计算器 封装套接字操作 服务端代码 服务进程执行例程 启动网络版服务端 协议定制 客户端代码 代码测试 使用JSON进行序列化与反序列化 我们程序员写的一个个解决我们实际问题&#xff0c;满…

新品发布会媒体邀请,邀约记者现场报道

传媒如春雨&#xff0c;润物细无声&#xff0c;大家好&#xff0c;我是51媒体网胡老师。 新品发布会媒体邀请及记者现场报道邀约流程&#xff1a; 一、策划准备 明确新品发布会时间、地点和主题。 制定媒体邀请计划&#xff0c;确定目标媒体。 二、邀请媒体 向目标媒体发送…

后端面试题整理-1

1.Maven 依赖传递产生版本冲突怎么解决&#xff1f; 升级或降级依赖版本&#xff1a;通过修改相关依赖的版本号&#xff0c;选择与项目其他依赖兼容的版本。可以通过查看 Maven 依赖树来确定哪些依赖冲突&#xff0c;并找出合适的版本号进行调整。排除依赖&#xff1a;对于特定…

CSS的三种定位,响应式web开发项目教程

标准文档流 文档流&#xff1a;指的是元素排版布局过程中 戳这里领取完整开源项目&#xff1a;【一线大厂前端面试题解析核心总结学习笔记Web真实项目实战最新讲解视频】 &#xff0c;元素会默认自动从左往右&#xff0c;从上往下的流式排列方式。并最终窗体自上而下分成一行行…

12、电源管理入门之clock驱动

目录 1. clock驱动构架 1.2 clock consumer介绍 2. Clock Provider 2.1 数据结构表示 2.2 clock provider注册初始化 2.3 DTS配置 2.4 clock驱动实现举例: 3. clock consumer 3.1 获取clock 3.2 操作clock 3.3 实例操作 4. SoC硬件中的使用 参考: 电源管理的两个…

记录一下go的包管理

如何降低版本 假设go版本go.mod: go 1.16运行项目&#xff0c; 查看运行报错&#xff0c;根据报错信息&#xff0c;一条一条解决 go run main.go错误: /home/server1/go/pkg/mod/google.golang.org/grpcv1.58.2/internal/buffer/unbounded.go:92:34: undefined: any类似这样的…

QT延时/等待

一、阻塞型延时 阻塞的原理就是&#xff1a;在延迟期间&#xff0c;本线程的事件循环得不到处理 1.QThread类的sleep() 最简单的延时方法就是使用QThread类的sleep(n)、msleep(n)、usleep(n)&#xff0c;这几个函数的不良后果就是&#xff0c;GUI会在延时的时间段内失去响应…

《 前端 vs. 后端:挑战与机遇的对决》

前言 前端开发和后端开发是构建网站、应用程序和其他软件的两个主要方面。它们各自负责不同的任务和功能。 前端开发: 定义:前端开发是指构建用户直接与之交互的网站或应用程序的过程。前端开发主要关注于用户界面和用户体验。技术栈:前端开发通常涉及使用 HTML、CSS 和 Ja…

组基轨迹建模 GBTM的介绍与实现(Stata 或 R)

基本介绍 组基轨迹建模&#xff08;Group-Based Trajectory Modeling&#xff0c;GBTM&#xff09;&#xff08;旧名称&#xff1a;Semiparametric mixture model&#xff09; 历史&#xff1a;由DANIELS.NAGIN提出&#xff0c;发表文献《Analyzing Developmental Trajectori…

7.1.3 Selenium的用法2

目录 1. 切换 Frame 2. 前进后退 3. 对 Cookies 操作 4. 选项卡管理(了解) 5. 异常处理 6. 反屏蔽 7. 无头模式 1. 切换 Frame 我们知道网页中有一种节点叫作 iframe&#xff0c;也就是子 Frame&#xff0c;相当于页面的子页面&#xff0c;它的结构和外部网页的结构完全…