Linux复习 / 文件系统QA梳理

news2025/2/25 19:17:57

文章目录

    • 前言
    • Q&A
      • 文件的基本理解
        • Q:谈谈你是怎么理解文件的?
        • Q:什么是当前工作路径?
        • Q:文件与操作系统有着怎样的关系?
        • Q:为什么语言要封装系统接口?
      • 文件描述符
        • Q:系统和进程是怎样管理文件的?
        • Q:文件描述符的分配规则是怎样的?
        • Q:如何理解Linux下一切皆文件(Linux怎样将硬件也看成文件)?
      • 重定向
        • Q:重定向的原理是什么?
        • Q:如何使用重定向函数dup2?
      • 语言级别的缓冲区
        • Q:何为缓冲区?
        • Q:缓冲区的意义是什么?
        • Q:语言级别的缓冲区在哪?
        • Q:缓冲区的刷新策略有哪些?

前言

本篇博客梳理关于Linux文件系统相关Q&A,若读者也在复习这块知识,或者正在学习这块知识,可以通过这些Q&A检测自己的知识掌握情况。此外,思维导图已经更新至我的gitee,Q&A之外的体系梳理还请移步思维导图。

Q&A


文件的基本理解

Q:谈谈你是怎么理解文件的?

A:

  1. Linux中,文件由文件属性和文件内容组成,即使一个文件为空,它的大小也不可能是0。因为文件 = 文件内容 + 文件属性,文件属性(文件创建时间、文件所有者等)不可能为空,文件就不可能为空
  2. 和程序一样,文件在没有被打开之前存储在磁盘上,打开文件的本质是将文件从磁盘加载到内存中。所以打开文件使磁盘文件变为内存文件
  3. 我们使用fopen、fwrite这样的语言函数操作文件,这些函数将被编译形成程序。只有程序运行起来成为进程后,我们对文件的操作才能实现,所以其实是进程在替我们操作文件。只有搞懂了进程与文件间的关系,我们才能深刻理解文件操作

Q:什么是当前工作路径?

A:使用命令"ll /proc/进程pid"可以查看指定进程的信息,其中有两个字段cwd与exe。cwd是该进程的当前工作路径,exe是该进程对应的可执行文件完整的路径。

一般情况下,当前工作路径和可执行文件所在目录是相同的,若可执行文件打开一个不存在的文件,该文件会被创建在当前工作路径下。但当前工作路径和可执行文件所在目录无关。使用chdir函数可以修改cwd,之后创建的新文件会被存储到新的工作路径下,此时新文件和可执行文件不在同一目录下。

Q:文件与操作系统有着怎样的关系?

A:文件被操作系统管理。文件属于磁盘资源的一部分,而操作系统作为系统资源的管理者,管理者磁盘资源,所以操作系统需要对文件进行管理。我们(进程)对文件进行的操作需要告知其管理者(操作系统),不能绕过管理者访问被管理的资源,这会使资源陷入不可控状态。所以,文件操作一定贯穿了操作系统。

Q:为什么语言要封装系统接口?

A:一些函数调用,如:scanf,fopen涉及到系统资源的访问,只要访问系统资源就必须经过操作系统。所以语言需要封装操作系统向上提供的接口以访问操作系统管理的资源。不同操作系统提供的接口存在差异,语言采用穷举所有操作系统+条件编译的方式,实现对不同操作系统的兼容,使函数调用者与系统接口解耦,只需关注语言提供的统一的接口。并且语言提供的接口比系统接口简单,使用便捷,学习成本低。


文件描述符

Q:系统和进程是怎样管理文件的?

A:在系统中,文件信息使用struct file结构体描述,并用数据结构将struct file维护起来。在进程中,task_struct是进程控制块,其中有一个files指针,指向了struct files_struct结构体,该结构体包含了一个数组fd_array[],其类型为struct file*,也就是系统描述文件信息的结构体。在fd_array数组中,文件描述符作为数组下标,对应的位置存储struct file指针,指向了系统的struct file。它们之间的关系图如下:

image.png
若进程新打开了一个文件,系统先创建struct file结构体,将其添加到队列中,接着进程在fd_array[]数组的空位置(存储nullptr的位置)写入该struct file的地址,数组位置的下标就是文件的文件描述符。

Q:文件描述符的分配规则是怎样的?

A:文件描述符会优先使用最小的没有被使用的下标。open打开一个文件,系统会从头开始遍历fd_array[]数组,只要找到空位置就将文件的struct file指针写入该位置,并且将该位置的下标(文件描述符)作为open函数的返回值返回。

Q:如何理解Linux下一切皆文件(Linux怎样将硬件也看成文件)?

A:操作系统无法直接操作硬件,只能通过硬件厂商提供的驱动操作硬件,驱动中封装了操作硬件的相关函数。一个设备极大概率有读和写两个操作,这两个操作封装在驱动程序中。而struct file结构体有两个函数指针,分别指向了驱动的读函数和写函数(这是C语言中的面向对象思想),假设进程需要读取磁盘,那么操作系统会通过进程找到磁盘对应的struct file结构体,通过其中的读指针找到磁盘的读函数,也就是驱动中的读函数,并且调用它。如果硬件没有读或写方法,那么struct file结构体中对应的函数指针为空。

image.png

总结一下:Linux使用struct file结构体以统一视角看待软硬件,软件有读/写方法,硬件大概率也是有的,Linux通过struct file中的函数指针,以面向对象的方式指向软硬件的读/写方法,若软硬件没有读写方法,那么该函数指针为空。

所以Linux用虚拟文件系统,将进程与硬件进行了解耦,并且使进程以统一的视角(文件)看待软硬件,以统一的方式管理不同的资源,通过‘加一层’的方式使进程的设计与实现更加的简单。


重定向

Q:重定向的原理是什么?

A:重定向的含义是:改变数据的流动方向。本该向A输出的数据,却输出到了B。

操作系统通过文件描述符标识文件,并且默认将fd为0、1、2的文件视为标准输入流、标准输出流、标准错误流,上层的语言设计文件操作接口也是如此。stdin、stdout、stderr对应的fd为0、1、2,printf本质上是对stdout文件进行输出,对应的fd为1,如果fd为1的文件不再是stdout而是其他文件,那么本该输出到标准输出的数据将会被输出到其他地方,这就是重定向。

由于文件描述符只是task_struct中fd_array[]数组的下标,我们只要改变fd_array[]数组的内容,使文件描述符指向其他文件,就可以实现重定向。比如关闭了fd为1的文件,此时创建新文件,根据文件描述符的分配规则,新文件的fd为1,此时使用printf输出数据,数据将被重新的到新文件,而不是屏幕(标准输出)上。

可以实现重定向的原因是:操作系统只根据fd识别文件,而高级语言默认将0、1、2文件对应标准输入、标准输出、标准错误。在改变底层的fd指向的文件的前后,使用C语言向标准文件流输入输出,可能得到不同的结果。

image.png

Q:如何使用重定向函数dup2?

A:函数原型

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

函数参数是两个文件描述符,该函数会将oldfd拷贝覆盖到newfd。从原理的角度上理解:系统将fd_array[]数组中下标为oldfd元素拷贝到下标为newfd的位置上,使原newfd位置的struct file*指针被覆盖为oldfd位置的struct file\,此时再向newfd输出/输入,数据就被重定向到oldfd文件中。

比如:

dup2(1, 2);

将标准错误流重定向到标准输出流,此时再向标准错误流输出数据,数据会被输出到标准输出中。关于返回值:若重定向成功,函数返回newfd的值,若重定向失败,函数返回-1并设置errno。

总结:dup2有两个参数,后一个参数对应的文件输入/输出会被重定向到前一个文件。

语言级别的缓冲区

Q:何为缓冲区?

A:使用语言级别的文件接口向文件进行输入/输出时,数据不会直接递达对应文件/递达进程本身,而是被放入缓冲区中,当缓冲区的数据满足刷新条件时,这些数据才会从缓冲区中被移除,进行下一步动作。

Q:缓冲区的意义是什么?

A:解放进程,提高进程的工作效率,减少进程的IO次数。进程将数据放入缓冲区中,不进行真正的IO,只有缓冲区中的数据满足刷新条件时,才会进行真正的IO,这样的集中IO提高了进程的传输效率。并且进程与磁盘这样的低速设备进行IO时,每次IO的速度极慢,集中IO的同时也减少了IO次数,整体上减少了进程IO的时间。

Q:语言级别的缓冲区在哪?

A:根据之前的认识,c语言有一个结构体FILE,其中封装了系统级别的文件描述符,除此之外FILE中还有一个缓冲区结构。所以说,语言级别的缓冲区有语言的结构进行维护,缓冲区封装在FILE结构中。

Q:缓冲区的刷新策略有哪些?

A:

  • 常规刷新:
    1. 无缓冲:直接将数据进行IO,如write函数
    2. 行缓冲:将换行符’\n’之前的数据(一行的数据)进行IO,如printf,fprintf
    3. 全缓冲:直到缓冲区满,才会进行IO,如块设备:磁盘
  • 特殊刷新:
    1. 使用语言函数fflush进行强制缓冲区数据刷新
    2. 进程退出时,会清空文件缓冲区中的数据,清空的操作就是强制刷新

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

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

相关文章

基于JSP的网上购物系统的设计与实现(论文+源码)_kaic

摘 要 近些年来&#xff0c;社会的生产力和科技水平在不断提高&#xff0c;互联网技术也在不断更新升级&#xff0c;网络在人们的日常生活中扮演着一个重要角色&#xff0c;它极大地方便了人们的生活。为了让人们实现不用出门就能逛街购物&#xff0c;网络购物逐渐兴起慢慢变得…

ES6(声名、解构)

参考文档&#xff1a; ES6 入门教程https://es6.ruanyifeng.com/ 注意&#xff1a;内容较多&#xff1a;只看引用部分的内容即可&#xff08;代码一眼过搭配理解&#xff09; 一、变量声明 1. let let声名的变量只在所处于的块级有效 let a 10; if (true) {let b 20;cons…

人工智能 AI 绘画发展史

到了去年4月, 著名人工智能团队OpenAI 也发布了新模型 DALLE 2代&#xff0c;该名称来源于著名画家达利&#xff08;Dal&#xff09;和机器人总动员&#xff08;Wall-E&#xff09;, 同样支持从文本描述生成效果良好的图像. 而很多读者对AI绘画开始产生特别的关注, 或许是从以下…

有趣的Hack-A-Sat黑掉卫星挑战赛——AES加密通信链路侧信道攻击leaky

国家太空安全是国家安全在空间领域的表现。随着太空技术在政治、经济、军事、文化等各个领域的应用不断增加&#xff0c;太空已经成为国家赖以生存与发展的命脉之一&#xff0c;凝聚着巨大的国家利益&#xff0c;太空安全的重要性日益凸显[1]。而在信息化时代&#xff0c;太空安…

如何将Springboot项目通过IDEA打包成jar包,并且转换成可执行文件

首先在IDEA打开你的项目&#xff0c;需要确认项目可以正常运行&#xff0c;然后点击页面右侧的Maven,运行Lifecycle下的package, 此时在项目的target目录下就可以看到一个jar包 这个时候你可以在jar包所在目录下执行cmd窗口&#xff0c;运行 java -jar campus-market-0.0.1-S…

BUUCTF-SimpleRev

下载文件 查壳 没有加壳 并且是64 放入ida64 SHIFTF12 访问字符串 得到关键字符串 双击 然后 CRTLX 查找交互 F5 反编译 得到了代码 开始代码审计 我们可以发现有两个十六进制的东西 r 对其转换为字符串 srcSLCDN v9wodah 然后继续往下看 发现textjoin函数 我们进入看…

STM32+AT24C02实现易变参数存储

AT24C02是一个2K位串行CMOS E2PROM&#xff0c; 内部含有256个8位字节存储单元&#xff0c;该器件通过IIC总线接口进行操作&#xff0c; AT24C02把存储空间分为 32 页&#xff0c;每页可存储8个字节的数据&#xff0c;具有硬件数据写保护功能&#xff0c;100万次擦写&#xff0…

Docker理论总结

目录 容器技术的演变 物理机时代 虚拟化时代 容器化时代 容器化技术的应用场景 Docker介绍与基本概念 标准化的应用打包 Docker的发展 Docker是容器化平台 Docker体系架构 容器与镜像 Docker执行流程 容器内部 Tomcat容器内部结构 在容器中执行命令 容器生命周…

( “树” 之 DFS) 104. 二叉树的最大深度 ——【Leetcode每日一题】

104. 二叉树的最大深度 给定一个二叉树&#xff0c;找出其最大深度。 二叉树的深度为根节点到最远叶子节点的最长路径上的节点数。 说明: 叶子节点是指没有子节点的节点。 示例&#xff1a; 给定二叉树 [3,9,20,null,null,15,7]&#xff0c; 返回它的最大深度 3 。 思路&am…

深度学习TensorFlow

博主简介 博主是一名大二学生&#xff0c;主攻人工智能研究。感谢让我们在CSDN相遇&#xff0c;博主致力于在这里分享关于人工智能&#xff0c;c&#xff0c;Python&#xff0c;爬虫等方面知识的分享。 如果有需要的小伙伴可以关注博主&#xff0c;博主会继续更新的&#xff0c…

redis整理之-持久化

redis整理之-持久化5. 持久化5.1 持久化简介5.1.1 场景-意外断电5.1.2 什么是持久化5.2 RDB5.2.1 save指令5.2.2 bgsave指令5.2.3 save配置自动执行5.2.4 RDB三种启动方式对比5.3 AOF5.3.1 AOF概念5.3.2 AOF执行策略5.3.3 AOF重写5.3.4 AOF工作流程及重写流程5.4 RDB与AOF区别5…

python开发环境的安装,PyCharm+python解释器

文章目录注意&#xff1a;软件打包下载&#xff1a;PyCharm的下载与安装下载安装python解释器的下载与安装下载安装PyCharm软件设置注意&#xff1a; 以下是Windows下的安装&#xff0c;Linux以及其他操作系统下的安装请类比参照&#xff01; 软件打包下载&#xff1a; PyCh…

主干网络backbone讲解—— Conv4与Resnet12

1 Conv4 在一些论文中&#xff0c;也称为Conv-64F。其中“64F”表示网络中使用了64个滤波器&#xff08;filters&#xff09; 它包含 4 个重复的卷积块&#xff0c;在每个块中包含&#xff1a; 一个 kernel3&#xff0c;stride1&#xff0c;padding1的卷积层&#xff1b;一个…

jquery中的ajax方法怎样通过JSONP进行远程调用

关于JSONP的概念以及为什么要使用JSONP您可以参考JSONP教程&#xff0c;本文的重点在于演示下在JQUERY中的Ajax方法怎样通过JSONP进行远程调用。 $.ajax的参数 首先介绍下$.ajax的参数&#xff1a; type&#xff1a;请求方式 GET/POST url:请求地址 async:布尔类型&#xff…

第十四届蓝桥杯大赛软件赛省赛 C/C++ 大学 A 组题解+个人总结

提示&#xff1a;此题解为本人自己解决&#xff0c;如有差错请大家多多指正。 文章目录题解总结一、幸运数1.试题2.解法3.代码二、[有奖问答](https://blog.csdn.net/A2105153335/article/details/130038980?spm1001.2014.3001.5501)三、[平方差](https://blog.csdn.net/A2105…

spring 随笔 ioc/di 4-Bean生命周期钩子

0. RUN&#xff0c;或8RUN&#xff0c;是每年都会思考的问题 Spring框架后置处理器PostProcessor详解 BeanDefinitionRegistryPostProcessor 扩展接口 动态注册bean AOP的高级特性targetSource AnnotationAwareAspectJAutoProxyCreator#postProcessBeforeInstantiation源码解析…

第五十九章 线段树(二)

第五十九章 线段树&#xff08;二&#xff09;一、懒标记&#xff08;lazy_tag&#xff09;1、作用2、思路二、结构体定义三、带有懒标记的函数操作1、pushup函数2、build函数3、modify函数4、pushdown函数5、query函数四、代码一、懒标记&#xff08;lazy_tag&#xff09; 1、…

redis五大基本数据类型之(源码分析)

redis五大数据结构StringHashsetListZset总结String String 是最基本的 key-value 结构&#xff0c;key 是唯一标识&#xff0c;value 是具体的值&#xff0c;value其实不仅是字符串&#xff0c; 也可以是数字&#xff08;整数或浮点数&#xff09;&#xff0c;value 最多可以…

远程桌面连接是什么?远程桌面连接使用教程

有时候电脑出现各类网络连接、网址访问出错问题&#xff0c;自己无法解决的情况下&#xff0c;常常会求助其他擅长IT的同事或朋友&#xff0c;要么自己通过社交工具在线沟通、要么抱着电脑找人家解决。然而&#xff0c;通过远程桌面完全可以让朋友同事远程帮自己查看电脑问题&a…

永远加载不满的进度条

前言 各位开发大佬&#xff0c;平时肯定见到过这种进度条吧&#xff0c;一直在加载&#xff0c;但等了好久都是在99% 如下所示&#xff1a;有没有好奇这个玩意儿咋做的呢&#xff1f;细听分说 &#xff08;需要看使用&#xff1a;直接看实践即可&#xff09; fake-progress …