深入理解linux中的文件(上)
1.前置知识:
(1)文章 = 内容 + 属性
(2)访问文件之前,都必须打开它(打开文件,等价于把文件加载到内存中)
如果不打开文件,文件就在磁盘中
(3)谁会去访问一个文件,进程。进程被加载启动之后,运行到fopen,才会打开一个文件
(4)手绘的进程和文件系统之间的交互图( 必看!!!):
2.C语言fopen函数:
#include <stdio.h>FILE *fopen(const char *path, const char *mode);
path: 指向你想要打开的文件路径的字符串。mode: 字符串,指定文件的打开模式。打开模式
mode参数决定了文件是如何被打开的。常见的模式有:
"r": 只读方式打开文本文件。文件必须存在。"w": 只写方式打开文本文件。如果文件存在则将其截断为零长度;如果文件不存在,则创建新文件。"a": 追加方式打开文本文件。如果文件存在,则在文件末尾添加数据;如果文件不存在,则创建新文件。"rb","wb","ab": 分别对应上面的二进制文件版本。"r+","w+","a+": 对应的读写版本(既可读也可写)。"rb+","wb+","ab+": 读写模式下的二进制文件版本。
3.系统级接口open:
open系统级接口,我们熟知的fopen是C语言的语言级接口,fopen底层封装的就是open
#include <fcntl.h>int open(const char *pathname, int flags); int open(const char *pathname, int flags, mode_t mode);
pathname: 指向你想要打开或创建的文件路径的字符串。flags: 这个参数可以包含多个标志的按位或组合,用于指定文件的打开方式(例如:只读、只写、读写等)。mode: 当创建新文件时(通过使用了O_CREAT标志),这个参数指定了新文件的权限模式。常见标志
O_RDONLY: 只读方式打开文件。O_WRONLY: 只写方式打开文件。O_RDWR: 读写方式打开文件。O_CREAT: 如果指定的文件不存在,则创建之。O_TRUNC: 如果文件存在并且以写方式或者读写方式打开,则将其长度截断为0。O_APPEND: 每次写操作前都会将文件指针移动到文件末尾。返回值
成功时,
open函数返回一个新的文件描述符;失败时返回-1并设置errno来指示错误类型。
4.文件描述符(open函数的返回值)
操作系统中,只认识 “文件描述符” :<0,代表打开文件失败
0 1 2 分别代表 键盘文件(标准输入)显示器文件(标准输出)显示器文件(标准错误流)
接下来打开的文件顺序是从3号开始
每一个进程,执行到open,创建struct file结构体,然后在file_struct数组中一个位置连接这个struct_file结构体,就会把数组的下标作为返回值fd1, 放回给进程。(fd的分配规则,最小的,没有被使用的fd!)
1. 创建struct file结构体
2. 数组链接结构体
3. 把数组下标返回给进程

5. C语言对操作系统中的文件操作进行了两个封装:
1.接口封装 fopen(C语言级接口) -> open(系统级接口)
2.类型封装 FILE (结构体,里面肯定包含文件描述符)-> int (文件描述符,下标)
6. 为什么语言层面还要进行封装:
1.方便用户操作 (open需要使用各种标识
O_RDONLY...而fopen使用打开模式"r")2.不用考虑平台的切换,提高语言的可移植性(linux windows的open不同,但fopen一样)
7.理解struct file结构体:
最重要的三个部分:1.inode结构体指针 2.文件操作的结构体指针 3.文件内核级缓冲区指针
(1)inode结构体
当文件从磁盘加载到内存的时候,这个inode表就要被创建。
在磁盘中:文件 = 属性 + 内容。 inode中的数据,就是拷贝磁盘中文件的属性。
当我讲那些没有被打开的文件时,我还会重谈inode表中的索引指针!

(2)文件操作表:
保存文件操作的函数指针。进程中的write(),会调用struct file -> f_op ->write ->写入内核级缓冲区
(由操作系统决定什么时候将内核级缓冲区中的数据写入到磁盘。系统级接口 fsync ( fd )可以刷新内核级缓冲区)

(3) 文件内核级缓冲区:
文件内核级缓冲区完全由操作系统管理,旨在提供高效、可靠的文件I/O操作,同时尽量减少用户空间应用对此过程的干预需求。这种设计使得大多数应用程序无需关心底层存储细节,即可获得良好的性能表现。
8. 输入输出重定向:
close(1);
file1.txt;
printf(“hello”);
fflush(stdout); //一定要执行这个操作,才会把内容写入到file1.txt中,也不显示到显示器上。
//如果没有执行fflush,内容不在file1.txt中,也不在显示器上显示。
首先,我们先不管fflush,假设他会写入到file1.txt中,这是为什么呢?
因为,close(1)会把显示器文件关闭,然后打开file1.txt是返回最小的,没有被使用的fd,那就是1了。这样子printf只认识fd==1的,就会写入到file1.txt文件中。
然后为什么需要fflush(stdout);stdout其实就是fd = 1;fflush是刷新语言级别的缓冲区! (这里引入一个新概念,语言级别缓冲区)
输出重定向 int dup2(int oldfd,int newfd ); //但是这里有认知偏差,如果要把1覆盖, dup2(fd,1);
在数组中,把新的地址,浅拷贝到原先的地址,当上层使用文件描述符(下标)的时候,就会重定向到目标文件!
(dup2还会把多余的指向目标文件的指针进行清除,没人指向的那一个,一般会自动关闭!)
oldfd 和 newfd都是 文件描述符。
你也可以不使用fflush来刷新,而是使用fclose来刷新,因为fclose不但封装了close系统调用,而且还封装了fflush。
那么为什么close不能自动刷新呢?因为fflush是刷新语言级缓冲区,而close是系统级调用,语言级缓冲区还在系统调用之上,close根本就看不到语言级缓冲区。
9.语言级别缓冲区:
因为在写入或者读取的时候,不断访问内核级缓冲区(调用系统调用),会有明显的消耗。所以在语言层面,还有一个语言级别的缓冲区。当我们printf的时候,只是写入到语言级缓冲区,还需要使用fflush写入到内核级缓冲区中。
语言级别缓冲区的三种刷新方式:
- 显示器文件: 行刷新 ,遇到 \n 刷新
- 写入磁盘文件(普通文件):缓冲区写满再刷新
- 不缓冲:直接调用系统接口
相关文章:
深入理解linux中的文件(上)
1.前置知识: (1)文章 内容 属性 (2)访问文件之前,都必须打开它(打开文件,等价于把文件加载到内存中) 如果不打开文件,文件就在磁盘中 (3&am…...
Unity特效插件GodFX
2022Unity安装使用方法,将MinDrawer.cs文件MinAttribute改成UnityEngine.PostProcessing.MinAttribute 参考链接: Unity3D特效插件GodFX使用教程_哔哩哔哩_bilibili...
从 C 到 C++:理解结构体中字符串的存储与操作
对于刚入门 C/C 的程序员来说,字符串的存储和操作可能是个容易混淆的知识点。在 C 中,std::string 提供了非常友好的接口,我们可以轻松地在结构体中使用字符串类型,无需关注底层细节。然而,在 C 语言中,字符…...
Linux进阶——时间服务器
NTP是网络时间协议(network time protocol)的简称(应用层的协议),通过UDP123端口进行网络时钟同步。 Chrony是一个开源自由的网络时间协议NTP的客户端和服务器软件。它能让计算机保持系统时钟与时钟服务器(…...
力扣 295. 数据流的中位数
🔗 https://leetcode.cn/problems/find-median-from-data-stream/ 题目 数据流中不断有数添加进来,add 表示添加数据,find 返回数据流中的中位数 思路 大根堆存储数据流中偏小的数据小根堆存储数据流中偏大的数据若当前的 num 比大根堆的…...
【Linux】进程状态和优先级
个人主页~ 进程状态和优先级 一、进程状态1、操作系统进程状态(一)运行态(二)阻塞态(三)挂起态 2、Linux进程状态(一)R-运行状态并发执行 (二)S-浅度睡眠状态…...
携程Java开发面试题及参考答案 (200道-上)
说说四层模型、七层模型。 七层模型(OSI 参考模型) 七层模型,即 OSI(Open System Interconnection)参考模型,是一种概念模型,用于描述网络通信的架构。它将计算机网络从下到上分为七层,各层的功能和作用如下: 物理层:物理层是计算机网络的最底层,主要负责传输比特流…...
Docker 部署教程jenkins
Docker 部署 jenkins 教程 Jenkins 官方网站 Jenkins 是一个开源的自动化服务器,主要用于持续集成(CI)和持续交付(CD)过程。它帮助开发人员自动化构建、测试和部署应用程序,显著提高软件开发的效率和质量…...
深入理解开放寻址法中的三种探测序列
一、引言 开放寻址法是解决散列表中冲突的一种重要方法,当发生冲突(即两个不同的键通过散列函数计算得到相同的散列值)时,它会在散列表中寻找下一个可用的存储位置。而探测序列就是用于确定在发生冲突后,依次尝试哪些…...
图像噪声处理技术:让图像更清晰的艺术
在这个数字化时代,图像作为信息传递的重要载体,其质量直接影响着我们的视觉体验和信息解读。然而,在图像采集、传输或处理过程中,难免会遇到各种噪声干扰,如高斯噪声、椒盐噪声等,这些噪声会降低图像的清晰…...
linux运行级别
运行级别:指linux系统在启动和运行过程中所处的不同的状态。 运行级别之间的切换:init (级别数) 示例: linux的运行级别一共有7种,分别是: 运行级别0:停机状态 运行级别1:单用户模式/救援模式…...
深入剖析Electron的原理
Electron是一个强大的跨平台桌面应用开发框架,它允许开发者使用HTML、CSS和JavaScript来构建各种桌面应用程序。了解Electron的原理对于开发者至关重要,这样在设计应用时能更合理,遇到问题也能更准确地分析和解决。下面将从多个方面深入剖析E…...
C++ 游戏开发:完整指南
目录 什么是游戏开发? 为什么选择 C 进行游戏开发? C 游戏开发:完整指南 1. 理解游戏开发的基础 2. 学习游戏引擎 3. 精通 C 进行游戏开发 4. 学习数学在游戏开发中的应用 5. 探索图形编程 6. 专注于游戏开发的某一领域 7. 通过游戏项目进行实…...
WebForms SortedList 深度解析
WebForms SortedList 深度解析 引言 在Web开发领域,对于数据结构的理解与应用至关重要。其中,SortedList类在WebForms中是一个常用的数据结构,它能够帮助开发者高效地管理有序数据集合。本文将深入解析SortedList类在WebForms中的应用,包括其基本概念、常用方法、性能特点…...
【hot100】刷题记录(12)-回文链表
题目描述: 给你一个单链表的头节点 head ,请你判断该链表是否为 回文链表 。如果是,返回 true ;否则,返回 false 。 示例 1: 输入:head [1,2,2,1] 输出:true示例 2: …...
深入理解 Unix Shell 管道 Pipes:基础和高级用法 xargs tee awk sed等(中英双语)
深入理解 Unix Shell 管道(|) 1. 什么是管道(Pipe)? 管道(|)是 Unix/Linux Shell 中最强大的功能之一,它允许将一个命令的输出作为另一个命令的输入,从而实现数据流的处…...
[MySQL]事务的理论、属性与常见操作
目录 一、事物的理论 1.什么是事务 2.事务的属性(ACID) 3.再谈事务的本质 4.为什么要有事务 二、事务的操作 1.事务的支持版本 2.事务的提交模式 介绍 自动提交模式 手动提交模式 3.事务的操作 4.事务的操作演示 验证事务的回滚 事务异常…...
RS485接口EMC
A.滤波设计要点 L1为共模电感,共模电感能够衰减共模干扰,对单板内部的干扰以及外部的干扰都能抑制,能提高产品的抗干扰能力,同时也能减小通过485信号线对外的辐射,共模电感阻抗选择范围为120Ω/100MHz ~2200Ω/100MHz…...
快速上手mybatis教程
基础知识 MyBatis 是一款优秀的持久层框架,其核心组件主要包括以下部分: SqlSession 作用:SqlSession 是 MyBatis 的核心接口,负责与数据库进行通信,执行 SQL 语句,并返回查询结果。它是 MyBatis 的一次会…...
本地部署DeepSeek-R1保姆级教程
近期,我国一款开源模型 DeepSeek-R1以低成本和高性能震撼了全球科技界。该模型的开源性使开发者能够在本地环境中部署和运行,提供了更高的灵活性和控制力。如果你也想在本地部署 DeepSeek-R1,可以参考以下完整的教程,涵盖Mac 版本…...
JSON Schema驱动智能体交互:构建结构化协作的接口契约
1. 项目概述:一个为智能体交互而生的“接口契约” 在构建基于大型语言模型的智能体(Agent)系统时,我们常常会遇到一个核心痛点:如何让智能体之间、智能体与工具之间、甚至是智能体与外部系统之间,进行结构…...
EmotionBook开源项目:构建可计算的情绪数据模型与可视化分析系统
1. 项目概述:一个为情绪寻找容器的数字实验最近在GitHub上看到一个挺有意思的项目,叫“EmotionBook”。光看名字,你可能会联想到一本情绪日记,或者一个记录心情的App。但点进去之后,你会发现它远不止于此。这其实是一个…...
宝塔面板 SyntaxError: invalid syntax 报错 完美修复教程
宝塔面板 SyntaxError: invalid syntax 报错 完美修复教程 一、故障现象 宝塔面板版本:11.7.0 系统:Debian GNU/Linux 10 (buster) x86_64 Python3.7.9 访问网站列表/站点管理报错: SyntaxError: invalid syntax /www/server/panel/class/pan…...
GESP学习,如何判断孩子是否适合跳级
判断孩子是否适合跳级,核心是综合评估其学术能力、心理成熟度、社交适应力及政策合规性。以下是基于教育规律与官方政策的系统性判断标准: 一、学术能力:是否真正“学有余力” 1、成绩特别优异: 在当前年级中,各…...
终极指南:3分钟掌握Mouse Jiggler鼠标模拟器完整使用方法
终极指南:3分钟掌握Mouse Jiggler鼠标模拟器完整使用方法 【免费下载链接】mousejiggler Mouse Jiggler is a very simple piece of software whose sole function is to "fake" mouse input to Windows, and jiggle the mouse pointer back and forth. …...
MacBook远程控制Win10打游戏?聊聊Microsoft Remote Desktop的那些隐藏玩法和限制
MacBook远程控制Win10打游戏?Microsoft Remote Desktop的极限性能测试与实战技巧 当MacBook用户需要临时调用Windows电脑的资源时,远程桌面工具往往成为救急首选。但你是否想过,这类工具能否胜任游戏、视频剪辑甚至3D建模等高图形负载任务&am…...
Arm SystemReady ACS测试指南与硬件兼容性认证
1. SystemReady Band ACS测试概述 SystemReady Band是Arm公司推出的一套硬件兼容性认证标准,专门针对基于Arm架构的计算设备设计。这套标准的核心理念是确保采用Arm处理器的设备能够无缝运行主流操作系统,包括Linux发行版、Windows和各种BSD变体。作为硬…...
倍福官网改版后,如何用F12开发者工具找回消失的Twincat3老版本安装包(附4024.11下载链接)
倍福官网改版后如何找回消失的Twincat3老版本安装包 作为一名自动化工程师,你是否遇到过这样的困境:项目需要特定版本的Twincat3进行维护或兼容性测试,但倍福官网改版后,历史版本下载入口却神秘消失了?这种情况在工业软…...
对比直接购买与使用Taotoken Token Plan套餐的成本控制体验
🚀 告别海外账号与网络限制!稳定直连全球优质大模型,限时半价接入中。 👉 点击领取海量免费额度 对比直接购买与使用Taotoken Token Plan套餐的成本控制体验 1. 引言:个人开发者的成本困惑 作为个人开发者࿰…...
控制理论实践:从PID到MPC的Python实现与仿真调试
1. 项目概述:从“Gonzo”看控制理论在开源项目中的实践最近在GitHub上看到一个挺有意思的项目,名字叫“control-theory/gonzo”。光看这个标题,你可能会有点摸不着头脑——“控制理论”和“Gonzo”有什么关系?Gonzo这个词…...
