新闻详情

新闻详情

首页 / 资讯中心 / 详情

Linux文件(一).前传之基础IO

发布时间:2026/9/12 19:58:10来源:尧图网络
Linux文件(一).前传之基础IO
一.理解文件1.狭义理解①.文件内容属性。②.文件储存在磁盘上。③.磁盘是永久性存储介质因此⽂件在磁盘上的存储是永久性的。④.磁盘是外设即是输出设备也是输⼊设备。⑤. 磁盘上的⽂件本质是对⽂件的所有操作都是对外设的输⼊和输出简称IO。2.广义理解文件Linux下⼀切皆⽂件键盘、显⽰器、⽹卡、磁盘……这些都是抽象化的过程。3.文件 内容 属性①.对于0KB的空⽂件是占⽤磁盘空间的空文件也具有属性也要占空间②.⽂件是⽂件属性元数据和⽂件内容的集合⽂件属性元数据内容。③. 所有的⽂件操作本质是⽂件内容操作和⽂件属性操作。4.系统角度任何文件都必须先打开然后才能访问那么是谁打开了文件呢答案是进程。所以文件操作的本质是进程对文件进行操作。既然涉及到进程就事关OS也就是说想要访问文件(文件储存在磁盘)就是访问磁盘而管理磁盘的正是OS所以访问文件其实是去调用OS的接口。二.回顾1.如何将信息输出到显示器向显示器打印数据本质上就是对显示器这个文件进行写入(linux下一切皆文件)。2.stdin stdout stderr这是三个文件流是FILE类型的指针分别代表键盘文件显示器文件。c语言程序在启动的时候默认会打开这三个输入输出流(打开指向的文件)。那么为何要默认打开输入输出流呢程序运行几乎一定有输入输出如果每次写程序都要用fopen打开方式去打开文件代码会十分繁琐和冗余。就比如使用基础IO函数时需要手动打开文件那么每写一个helloworld或者用scanf获取一段数据都需要去手动打开屏幕文件和显示器文件特别麻烦。3.文件打开的方式①.w以w(写)的方式打开文件时默认会先将文件的内容清空。这里就能解释为什么用(重定向操作符)向文件写入内容时每写一次进去就把原来的东西覆盖掉一次。使用“时默认会先以写(w)的方式打开文件就会清空原来文件里的内容。②.a用这种方式打开的文件在写入数据时玩的是追加(向文件结尾处追加)也就是说不会想上面那样每打开一次文件就清空一次文件内容。在使用(追加重定向操作符)写入数据时会默认先以a的方式打开文件因此写入的数据是追加的三.系统文件IO打开⽂件的⽅式不仅仅是fopenifstream等流式语⾔层的⽅案其实系统才是打开⽂件最底层的⽅ 案。1.open就比如fopen是语言层面的接口当调用fopen时fopen其实还会去调用系统调用接口open。open的参数列表里有一个flags标记位我们先来明晰何谓标志位。①.标志位flags是一个整型的数据是宏。flags的几个宏把这些宏传入open可以让文件以不同方式被打开这也是语言层面fopen里w,“r”等打开方式的实现原理。来看一下各个宏的作用·O_RDONLY:只读打开·OWRONLY:只写打开·O_RDWR:读写打开·O_CREAT:若文件不存在则创建·O_TRUNC:打开文件的同时清空文件内容(Truncate)·O_APPEND:追加写模式这些宏是可以组合使用的在传参的时候用|连接就行了。fopen的“w和a打开方式的底层2.文件描述符fd到底是个什么鬼①.类型角度通 过对open函数的学习我们知道了⽂件描述符就是⼀个⼩整数是open的返回值。这里有个奇怪的现象当我们用open打开多个文件并打印它们对应的fd时怎么从3开始那么0,1,2去哪了呢答案是Linux进程默认情况下会有3个缺省打开的⽂件描述符分别是标准输⼊0标准输出1标准错 误2。前面说过标准输入输出错误这三位是系统默认打开的因此它们在系统默认打开时已经有fd了就已经把0,1,2占据了那系统调用open的上一层语言层面的接口fopen的返回值怎么又是FILE*类型的呢这里的FILE又是个什么玩意答案是在语言层面的FILE是一个typedef出来的结构体但在OS层面只认fd不认FILE。既然不认我语言层面又只有FILE但语言层面的接口的执行又要去调用系统调用接口那这该咋办呢答案是FILE里一定封装了fd!!!!②.内容角度那上面这些个fd数字(0,1,2,3,4)到底有啥含义呢答案是它们是数组下标那这个数组是用来干啥的呢上面有个结论打开文件的本质是进程打开文件属于操作系统的范畴。操作系统需要把打开的文件管理起来管理方式是先描述再组织。当进程打开文件时内核会创建一个struct file,上面的成员(包括内容属性)与磁盘上的文件是相对应的。打开多个文件就会创建多个对应的struct file。创建struct file就是先描述。所以再组织就是将各个文件对应的struct file链接起来所以OS对被打开文件的管理就是对链表的增删查改每个struct file都有一段缓冲区磁盘上对应文件的内容就会被加载到这个缓冲区上。所以打开(open)这个过程其实是创建struct file然后把文件的内容属性加载到对应的struct file上而执行读/写一类的操作就是从缓冲区里进行读写。那怎么分清哪些struct file是某一个对应进程创建的呢当一个进程被创建在进程的PCB里还会创建一个叫struct file_struct的文件描述符表。而这个表里会包含一个struct file*类型指针数组fd_arry[]。每个元素指向一个file_struct那么这些元素的下标就是上面的fd!!而属于系统调用的read函数的底层是去文件描述符表里索引找到对应的struct file,然后将其文件缓冲区的内容拷贝一份拷贝到用户层的缓冲区里所以read的本质是内核到用户空间的拷贝函数对文件的任何操作都必须先把文件加载到内核的struct file的缓冲区里假如要修改文件内容就先将文件内容加载到缓冲区内然后对缓冲区上的内容进行修改修改完成后将缓冲区内容写回磁盘。那加载的本质又是什么呢答案是从磁盘到内存的拷贝3.重定向的原理①.fd分配原则首先我们要明晰fd的分配原则当新的文件被加载进内存(被进程打开)OS就会去到文件描述符表里去查询将查到的最小的且没有被使用的空间的下标作为新的fd给用户。②.说回重定向下面代码演示了很有意思的一幕先将fd 1的输出流stdout关闭了然后同时打开一个log.txt文件并打印log,txt的fd到屏幕上。这时我们发现fd并没有打印到屏幕上而是写入了log,txt里这是什么鬼哈哈这就是出现了重定向我们来说说原理补充一点printf的底层是向stdout指向的屏幕文件写入而std只认fd 1也就是说下标fd 1的元素是屏幕文件才能向屏幕文件写入东西所以重定向的本质是是去修改files_struct里指定下标所对应元素(指针)的指向。也就是用新文件的struct file的地址去覆盖旧的地址。这里还有个系统调用——dup2可以用来重定向用newfd对应的地址去覆盖oldfd对应的地址。使得oldfd的地址指向新文件的 struct file。也就是说oldfd对应的指针最终是newfd对应指针的一份拷贝所以形参要传newfd和oldfd重定向 打开文件的方式 dup2。最后再来说一个点上面fd 1的指针经重定向指向新的 struct file那么原来的 struct file该怎么解决呢会不会造成空间无法释放进而造成浪费呢答案是struct file上有个计数器ref_cnt。同时由于一个文件支持多个进程打开也就是说这些进程的files_struct上都会有指针指向这个struct file每多一个指针指向ref_cnt就一次相反每少一个指针指向ref_cnt就--一次当ref_cnt 0的时候OS会将这个struct file释放掉。四.理解一切皆文件在linux包括硬件设备也是抽象的文件每种硬件设备在驱动层都具有一套自己的读写方法而且不同设备读写方法完全不同。之前说过OS对硬件管理是先描述再组织将硬件设备生成对应的结构体并将不同的硬件的结构体链接起来。想要对某个设备执行写/读操作时会通过以下的调用链注意先将设备打开加载到内存上形成对应的struct file。
网站建设高端定制企业官网
RELATED

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

最新相关资讯

RTL8153b替代新选择:方寸微PT153s芯片迁移与千兆网卡设计实战 2026/9/12 20:43:16

RTL8153b替代新选择:方寸微PT153s芯片迁移与千兆网卡设计实战

做硬件这些年,我最怕的不是设计难点,而是明明方案已经量产了,突然告诉你核心芯片缺货,或者价格翻倍,那感觉就像辛辛苦苦盖了大楼,结果地基材料被人抽走了。前阵子在做一款便携USB千兆网卡,原来一…

阅读更多 →
字轮水表读数识别:OpenCV定位+CNN分类的OCR工程化实践 2026/9/12 20:43:16

字轮水表读数识别:OpenCV定位+CNN分类的OCR工程化实践

简介:一套Python字轮式自来水水表识别项目源码,面向具备基本Python语法、希望深入计算机视觉与机器学习实战的开发者,解决自动读取字轮水表数字的问题。项目以OpenCV为图像处理核心,覆盖灰度化、二值化、直方图均衡化、边缘检测等…

阅读更多 →
@composio/slim:Composio TypeScript SDK 的轻量化构建包完整指南 2026/9/12 20:43:16

@composio/slim:Composio TypeScript SDK 的轻量化构建包完整指南

composio/slim:Composio TypeScript SDK 的轻量化构建包完整指南 【免费下载链接】composio Composio powers 1000 toolkits, tool search, context management, authentication, and a sandboxed workbench to help you build AI agents that turn intent into act…

阅读更多 →
Karpathy式LLM工程实践:用claude.md与Claude Code构建可审计工作流 2026/9/12 20:43:16

Karpathy式LLM工程实践:用claude.md与Claude Code构建可审计工作流

1. 项目概述:这不是一份“技能清单”,而是一份LLM时代工程师的生存地图你点开这个标题——“andrej-karpathy-skills”——大概率不是想查Andrei Karpathy的LinkedIn履历,也不是要背诵他2017年那场经典演讲里的金句。你真正想问的是&#xff…

阅读更多 →
Java系统假死问题诊断与MAT工具实战指南 2026/9/12 20:43:16

Java系统假死问题诊断与MAT工具实战指南

1. 线上系统假死问题的典型表现与初步诊断假死问题是Java线上系统中最令人头疼的故障之一,系统看似在运行(进程存在、端口可连接),但实际已丧失服务能力。去年我们电商大促期间就遭遇过订单服务假死,表面看JVM的CPU和内…

阅读更多 →
用 wezterm.gui.default_key_tables() 继承并覆盖 WezTerm 默认键表:copy_mode 自定义实战指南 2026/9/12 20:40:16

用 wezterm.gui.default_key_tables() 继承并覆盖 WezTerm 默认键表:copy_mode 自定义实战指南

用 wezterm.gui.default_key_tables() 继承并覆盖 WezTerm 默认键表:copy_mode 自定义实战指南 【免费下载链接】wezterm A GPU-accelerated cross-platform terminal emulator and multiplexer written by wez and implemented in Rust 项目地址: https://gitcod…

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞