当前位置: 首页 > news >正文

Linux 文件、重定向、缓冲区

个人主页:仍有未知等待探索-CSDN博客

专题分栏: Linux

目录

一、文件

1、文件的理解(浅层)

1.文件是什么?

2.文件操作的前提

3.文件的存储 

4.一个进程可以打开多个文件吗?如果可以怎么管理的? 

5.打开文件(fopen用法)

​编辑

选项‘w‘:

选项’a‘:

6、输出重定向

重定向:

追加重定向:

2、文件的理解(深层)

1.文件操作

本质:

底层逻辑: 

2.认识系统调用和文件操作

1、文件描述符fd

标准输出和标准错误都是向显示器中打印数据,他们俩有什么区别?

打开多个文件的时候,怎么存储在struct file_struct* fd_array[N]数组里面?

文件操作符表的分配规则?

2、打开(并创建)文件open

参数:

​编辑

返回值:

底层逻辑:

3、关闭文件close

参数:

返回值:

4、写入文件write

5、读文件read

返回值:

3.理解Linux一切皆文件

4.C语言中文件类型FILE

二、重定向和缓冲区

1、重定向

1.本质

2.重定向的理解

 3.重定义符号‘>’

2、缓冲区

1.stat:系统调用

参数:

2.缓冲区

为什么打印的时候不进行刷新就没有显示?

什么是缓冲区?

为什么要有缓冲区?

缓冲区是怎么刷新的?

a、提高刷新策略。

b、特殊情况。

C语言为什么要在FILE中提供用户级缓冲区?

为什么需要fd == 1、2?

 perror和printf的区别?

文件和缓冲区的关系


一、文件

1、文件的理解(浅层)

1.文件是什么?

文件 = 属性 + 内容。

2.文件操作的前提

程序运行是文件操作的前提。

文件操作就是cpu在执行代码,本质就是进程在操作文件。

3.文件的存储 

文件在没有打开的时候:文件的属性和内容存储在磁盘上。

文件打开的时候:文件的属性存储在内存里,文件的内容按需加载到内存中。

4.一个进程可以打开多个文件吗?如果可以怎么管理的? 

一个进程可以打开多个文件。

管理的本质就是先描述,在组织。

管理一个文件:为了能更好的描述文件,os内部会用一个结构体来记录文件的各种属性,结构体内部会有一个指针指向一个文件缓冲区,里面存储着文件的内容。

管理一堆文件:将每个文件所对应的结构体用一个数组进行存储。

5.打开文件(fopen用法)

选项‘w‘:

以 ’写‘ 的方式打开文件。

1、如果该文件不存在,就在当前路径下,新建一个文件。

2、默认打开的时候,会把目标文件清空。

选项’a‘:

以 ’追加‘ 的方式打开文件。

1、 默认打开的时候,不会把目标文件清空,而是在文件内容的后面进行追加。

6、输出重定向

重定向:

echo “aaa” > log.txt

  • 重定向一定是文件操作。
  • 以 ’w‘ 的方式打开文件。
追加重定向:

echo “aaa” >> log.txt

  • 追加重定向一定是文件操作。
  • 以 'a' 的方式打开文件。

2、文件的理解(深层)

1.文件操作

本质:

进程和文件的交互关系。

底层逻辑: 

---> 想要对文件进行操作。

---> 去磁盘中寻找文件(找到以指定方式打开,找不到则新建文件)。

---> 对其进行打开操作,然后需要外设对其进行输入或者输出操作。

---> 向文件进行写入,本质上是向硬件中写入。

---> os是硬件的管理者,用户没有权限对其进行修改。

---> 所以os提供了一系列的系统调用。

---> fopen/fwrite/fread/fpintf/scanf/printf/cin/cout都是对系统调用的封装。

2.认识系统调用和文件操作

1、文件描述符fd

文件描述符fd的本质就是存储文件信息的数组下标。

下面这个3个文件都是默认打开的。

fd == 0:标准输入,键盘 --- stdin。

fd == 1:标准输出,显示器 --- stdout。

fd == 2:标准错误,显示器 --- stdout。

标准输出和标准错误都是向显示器中打印数据,他们俩有什么区别?

在打印信息的时候,可以将标准输出和标准错误进行分离。

打开多个文件的时候,怎么存储在struct file_struct* fd_array[N]数组里面?

找到没有存储文件且下标最小的位置。

文件操作符表的分配规则?

查自己(进程)的文件操作符表,分配最小的没有被使用文件操作符fd。

由图可知:无论是读文件还是写文件,都将文件内容从磁盘中读取到文件级缓冲区中。

2、打开(并创建)文件open

参数:

pathname:

a.如果传的是路径,则在指定路径下打开文件。若没有该文件,则以指定方式,新建文件。

b.如果传的是文件名,则在当前路径下打开文件。若没有,则以指定方式,新建文件。

flags:

32位比特位,是指定打开文件的方式(有很多的系统的选项)。

O_WRONLY --- 只写

O_CREAT --- 创建

O_TRUNC --- 清空

O_APPEND --- 追加

O_RDONLY --- 只读

// 以只写、追加的方式打开文件,当当前路径没有文件时,创建文件;若有文件,则打开文件
int fd1 = open("test.txt", O_WRONLY | O_CREAT |O_APPEND, 0666);// 以只写、追加的方式打开文件,当当前路径没有文件时,不处理;若有文件,则打开文件
int fd2 = open("test.txt1", O_WRONLY | O_APPEND, 0666);
// 原理flags
// 这样就完成了各种选项的筛选#include <stdio.h>#define O_WRONLY (1)
#define O_CREAT (1 << 1)
#define O_APPEND (1 << 2)
#define O_RDONLY (1 << 3)
#define O_TRUNC (1 << 4)void func(int flags)
{if (flags & O_WRONLY)printf("O_WRONLY\n");if (flags & O_CREAT)printf("O_CREAT\n");if (flags & O_APPEND)printf("O_APPEND\n");if (flags & O_RDONLY) printf("O_RDONLY\n");if (flags & O_TRUNC)printf("O_TRUNC\n");printf("\n");
}
int main()
{func(O_WRONLY);func(O_WRONLY | O_CREAT);func(O_WRONLY | O_CREAT | O_APPEND);func(O_WRONLY | O_CREAT | O_APPEND | O_RDONLY);func(O_WRONLY | O_CREAT | O_APPEND | O_RDONLY | O_TRUNC);return 0;
}

mode:

如果有O_CREAT选项,并且在指定路径下,文件不存在,则新建文件的权限就是mode。

最终的文件权限 = ~unmark & mode

返回值:

返回的是打开文件或者新建文件的文件描述符fd。

底层逻辑:
  • 创建file。
  • 开辟文件缓冲区的空间,加载文件数据(延后加载、按需加载)。
  • 查进程中的文件描述符表。
  • 将 file 的struct_file的地址存入文件描述符表中。
  • 返回下标。
3、关闭文件close

参数:

fd 就是你要关闭的文件的fd。

返回值:

如果关闭成功,则返回 0 ;

如果关闭失败,则返回-1,并且设置了错误码errno。

4、写入文件write

将大小为 count 的 buf 里面的内容,写入到 fd 文件里面。

5、读文件read

从 fd 中 读数据,存储到buf中,count为能读取的最大字节数,即buf所指向的空间大小。

返回值:

返回值大于零,则代表实际读了多少字节。

3.理解Linux一切皆文件

对于fd == 0、1、2分别对应着不同的硬件,但是硬件是怎么和文件相关联上的呢?

4.C语言中文件类型FILE

建议使用的时候用语言层面的函数,即标准库函数。因为在不同的平台下面,系统调用的用法不一定相同。

FILE是一个C语言提供的结构体,里面一定封装了 fd 文件描述符。

FILE* fp = fopen("log.txt", "w");
// fp 里面封装了 fd:fp->fileno
// "w" == O_WRONLY | O_CREAT | O_TRUNC

二、重定向和缓冲区

1、重定向

1.本质

是在内核中改变文件描述符表特定下标的内容 和上层无关

2.重定向的理解

dup2的本质就是文件描述符下标对应的内容拷贝。

---> 将newfd文件关闭,把oldfd文件描述符放入newfd中,具体的效果就是下列的图

对应printf函数,在底层就已经默认是对fd==1的位置的文件中进行打印。

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>int main()
{// 把显示器关闭int fd = open("test.txt", O_WRONLY | O_CREAT | O_TRUNC);dup2(fd, 1);printf("I am test.c");return 0;
}

 3.重定义符号‘>’

格式:newfd > oldfd

2、缓冲区

1.stat:系统调用

stat系统调用的作用是:获取文件或者目录的状态信息(文件的各种属性)

参数:

struct stat* buf:是一种输出型参数。指向的是存储文件属性的结构体。

off_t st_size:文件的大小(字节)

2.缓冲区

为什么打印的时候不进行刷新就没有显示?

struct FILE* 这个结构体里有语言级别的文件缓冲区。

fflush()的作用是:将语言级别的缓冲区刷新到操作系统里面的内核文件缓冲区。

什么是缓冲区?

缓冲区就是一段内存空间。

为什么要有缓冲区?

给上层空间提供高效的IO体验,间接提高整体的效率。

缓冲区是怎么刷新的?
a、提高刷新策略。

立即刷新。fflush(stdout):用户级到内核级缓冲 区、fsync(int fd):内核级缓冲区到外设

行刷新。是为了照顾用户的习惯 --- 显示器

全缓冲。缓冲区写满才刷新。--- 普通文件

b、特殊情况。

进程退出,系统会自动刷新。

强制刷新。

C语言为什么要在FILE中提供用户级缓冲区?

为了减少底层调用系统调用的次数,让使用C语言的IO函数效率更高。

为什么需要fd == 1、2?

我们写的程序,本质都是对数据在进行处理(计算、存储),所以我们需要知道处理时候发生异常的原因。

打印到显示器的里面的信息,可能是正确的,可能是错误的。1、2都是往显示器中打印,这样的话,在文件层面,正确信息和错误信息就分开了,./a.out 1> log.txt 2> err.txt。 

 perror和printf的区别?

perror本质上是向2打印,而printf本质上是向1打印。

文件和缓冲区的关系

每一个文件都有自己的缓冲区和文件操作符表。

每个进程在操作系统中通过文件描述符来访问文件,并且这些访问可能涉及到由操作系统或应用程序库管理的文件缓冲区。

谢谢大家!!!

相关文章:

Linux 文件、重定向、缓冲区

个人主页&#xff1a;仍有未知等待探索-CSDN博客 专题分栏&#xff1a; Linux 目录 一、文件 1、文件的理解&#xff08;浅层&#xff09; 1.文件是什么&#xff1f; 2.文件操作的前提 3.文件的存储 4.一个进程可以打开多个文件吗&#xff1f;如果可以怎么管理的&#xf…...

WEB漏洞-SQL注入之MYSQL注入

跨库注入的原理&#xff1a;针对同一IP下的不同域名 同一服务器下 网站A对应数据库A 网站B对应数据库B 网站C对应数据库C 如果某网站的存在注入点&#xff0c;注入点的权限恰好是root权限&#xff0c;也就是最高权限&#xff0c;那么可以通过跨库注入获取其他网站的数据库…...

mysql 查询 from a, b 和 a left join b 有什么区别

在MySQL中&#xff0c;from a, b 和 a left join b 有显著的区别&#xff0c;主要体现在查询结果和使用场景上。 基本语法与返回结果&#xff1a; from a, b&#xff1a;这种写法实际上是将两个表作为一个整体来处理&#xff0c;即假设这两个表是同一个表。因此&#xff0c;它…...

禁用ssh 22端口

在Linux系统中&#xff0c;要关闭SSH端口&#xff0c;可以通过修改SSH配置文件或防火墙规则来实现。 方法一&#xff1a;修改SSH配置文件 1. 使用root用户登录Linux系统。 2. 打开SSH配置文件&#xff0c;可以使用任何文本编辑器&#xff0c;如vi或nano。在大多数Linux发行版上…...

C++基础编程的学习3

nullptr关键字 在C11之前&#xff0c;空指针通常用NULL或0表示。然而&#xff0c;这些表示方法存在类型安全问题。C11引入了nullptr关键字&#xff0c;它提供了一个明确的、类型安全的空指针值。 Lambda表达式 Lambda表达式是C11引入的一种便捷的匿名函数定义方式。当Lambda…...

Java中的Optional类:解锁优雅编程的秘密

引言 在Java开发的世界里&#xff0c;空指针异常&#xff08;NullPointerException&#xff09;一直是让无数程序员头疼的问题之一。它不仅打断了程序的正常执行流程&#xff0c;还可能隐藏在复杂的业务逻辑之中&#xff0c;难以定位。自Java 8起&#xff0c;一个新的类——Op…...

聆思CSK6大模型开发板语音控制风扇(上)

前言 本文介绍如何实现大模型语音交互对风扇实现开关控制&#xff0c;示例使用的硬件是聆思CSK6大模型开发板&#xff0c;大模型接的是星火大模型。本文将先详细介绍大模型云端从获取交互语音到下发控制指令的全过程&#xff0c;包括整合上下文、配置提示词、语义意图分类、提取…...

代码随想录算法训练营第四十一天 | 121. 买卖股票的最佳时机、122. 买卖股票的最佳时机II、123. 买卖股票的最佳时机III

一、121. 买卖股票的最佳时机 题目链接&#xff1a;121. 买卖股票的最佳时机 - 力扣&#xff08;LeetCode&#xff09; 文章讲解&#xff1a;代码随想录 (programmercarl.com)——121. 买卖股票的最佳时机 视频讲解&#xff1a;动态规划之 LeetCode&#xff1a;121.买卖股票的最…...

延时队列与redis and rabbitmq

延时队列是什么 延时队列&#xff08;Delay Queue&#xff09;是一种特殊的消息队列&#xff0c;它允许你在添加消息时设置一个延时时间&#xff0c;消息只有在延时时间到达后才能被消费。这种机制在分布式系统中非常有用&#xff0c;常用于处理需要在指定时间后执行的任务&am…...

数据结构--单链

#include "link.h" plink get_head() { plink pmalloc(sizeof(Link)); if(pNULL) { printf("申情节点失败\n"); return NULL; } p->len0; p->nextNULL; return p; } void head_insert(plink L,int a) {…...

春秋云镜CVE-2023-38836

打开靶场环境 点击发现一个登陆框&#xff0c;弱口令试一下 发现账号密码为admin,password 随便点击点击 Media发现这里可以上传文件上传木马试试 <?php eval($_POST["wjq"]); ?> 发现不能上传php文件 php内容 修改他的格式 抓包绕过一下 302就可以其实已经…...

Linux 进程概念

Linux 进程概念 硬件理解冯 诺依曼体系结构五大组成部件强调存储 引子操作系统&#xff08;Operator System&#xff09;概念作用认识为什么要有操作系统&#xff1f; 结构 示意图理解操作系统system call库函数概念 进程什么是进程概念误区认识 描述进程 - PCBtask_struct - P…...

【秋招突围】2024届校招-米哈游笔试题-第二套

🍭 大家好这里是 春秋招笔试突围,一起备战大厂笔试 💻 ACM金牌团队🏅️ | 多次AK大厂笔试 | 编程一对一辅导 ✨ 本系列打算持续跟新 春秋招笔试题 👏 感谢大家的订阅➕ 和 喜欢💗 和 手里的小花花🌸 ✨ 笔试合集传送们 -> 🧷春秋招笔试合集 🌰 明晚又有米…...

tklog v0.0.9 :Rust灵活高效日志管理

tklog是rust高性能结构化日志库&#xff0c;支持同步日志&#xff0c;异步日志&#xff0c;支持自定义日志的输出格式&#xff0c;支持按时间&#xff0c;按文件大小分割日志文件&#xff0c;支持日志文件压缩备份&#xff0c;支持官方日志库标准API&#xff0c;支持mod独立参数…...

长安链java-sdk打成jar包部署找不到配置文件,springBoot项目制作Docker镜像

长安链使用sdk_config.yml的形式来引入用户的各种证书文件&#xff0c; 但是打成jar包部署在服务器上会提示找不到文件。 由于国内对镜像的限制&#xff0c;我选用了阿里的龙蜥镜像&#xff0c;里面提供java1.8的环境&#xff0c;因为长安链要1.8的环境 docker pull anolis-…...

AI问答:理解软件开发中的几个概念 / 软件逆向、加密、加固、脱壳、反编译

一、软件逆向 定义软件逆向工程是指从程序系统出发&#xff0c;通过运用解密、反汇编、系统分析、程序理解等多种计算机网络安全技术&#xff0c;对软件的结构、流程、算法、代码等进行逆向的拆解分析&#xff0c;从而推出软件产品的源代码、设计原理、结构、算法、处理过程、…...

第十一届MathorCup高校数学建模挑战赛-C题:基于有限差分法的散热机理建模与海底数据中心优化设计

目录 摘 要 1 问题重述 1.1 问题背景 1.2 问题重述 2 问题分析 3 模型假设 4 符号说明 5 我们的工作 6 模型的建立与求解 6.1 建模前的准备 6.2 问题一的建模与求解 6.3 问题二的建模与求解 6.4 问题三的建模与求解 6.5 问题四的建模与解决 7 结果检验及误差分析 8 模型评价 9 …...

【java】常量

文章目录 什么是常量常量分类 什么是常量 程序运行过程当中&#xff0c;其值不可以发生改变的量。 常量分类 常量类型说明举例字符串常年用双引号括起来的内容“Hello World !” “我是一个常量”整数常量不带小数点的数字666 -888小数常量带小数的数字3.14、-3.19字符常量用…...

react如何使用useContext + TS 自定义hooks

为了在 TypeScript 中为 useContext 提供良好的类型提示&#xff0c;我们需要为 Context 定义类型&#xff0c;并确保在创建和使用 Context 时应用这些类型。这可以帮助我们获得更好的类型检查和智能提示。 示例&#xff1a;在用户认证示例中添加 TypeScript 类型 定义类型 …...

【网络安全学习】SQL注入03:如何防止SQL注入

防止SQL注入&#xff0c;就必须清楚&#xff1a;数据库只负责执行SQL语句&#xff0c;根据SQL语句来返回相关数据。数据库并没有什么好的办法直接过滤SQL注入&#xff0c;哪怕是存储过程也不例外。 那么防止SQL注入就得从代码层面进行入手。 1. 严格的数据类型 Java、C#等强…...

地震勘探——干扰波识别、井中地震时距曲线特点

目录 干扰波识别反射波地震勘探的干扰波 井中地震时距曲线特点 干扰波识别 有效波&#xff1a;可以用来解决所提出的地质任务的波&#xff1b;干扰波&#xff1a;所有妨碍辨认、追踪有效波的其他波。 地震勘探中&#xff0c;有效波和干扰波是相对的。例如&#xff0c;在反射波…...

synchronized 学习

学习源&#xff1a; https://www.bilibili.com/video/BV1aJ411V763?spm_id_from333.788.videopod.episodes&vd_source32e1c41a9370911ab06d12fbc36c4ebc 1.应用场景 不超卖&#xff0c;也要考虑性能问题&#xff08;场景&#xff09; 2.常见面试问题&#xff1a; sync出…...

高频面试之3Zookeeper

高频面试之3Zookeeper 文章目录 高频面试之3Zookeeper3.1 常用命令3.2 选举机制3.3 Zookeeper符合法则中哪两个&#xff1f;3.4 Zookeeper脑裂3.5 Zookeeper用来干嘛了 3.1 常用命令 ls、get、create、delete、deleteall3.2 选举机制 半数机制&#xff08;过半机制&#xff0…...

IoT/HCIP实验-3/LiteOS操作系统内核实验(任务、内存、信号量、CMSIS..)

文章目录 概述HelloWorld 工程C/C配置编译器主配置Makefile脚本烧录器主配置运行结果程序调用栈 任务管理实验实验结果osal 系统适配层osal_task_create 其他实验实验源码内存管理实验互斥锁实验信号量实验 CMISIS接口实验还是得JlINKCMSIS 简介LiteOS->CMSIS任务间消息交互…...

深入解析C++中的extern关键字:跨文件共享变量与函数的终极指南

&#x1f680; C extern 关键字深度解析&#xff1a;跨文件编程的终极指南 &#x1f4c5; 更新时间&#xff1a;2025年6月5日 &#x1f3f7;️ 标签&#xff1a;C | extern关键字 | 多文件编程 | 链接与声明 | 现代C 文章目录 前言&#x1f525;一、extern 是什么&#xff1f;&…...

Android 之 kotlin 语言学习笔记三(Kotlin-Java 互操作)

参考官方文档&#xff1a;https://developer.android.google.cn/kotlin/interop?hlzh-cn 一、Java&#xff08;供 Kotlin 使用&#xff09; 1、不得使用硬关键字 不要使用 Kotlin 的任何硬关键字作为方法的名称 或字段。允许使用 Kotlin 的软关键字、修饰符关键字和特殊标识…...

GC1808高性能24位立体声音频ADC芯片解析

1. 芯片概述 GC1808是一款24位立体声音频模数转换器&#xff08;ADC&#xff09;&#xff0c;支持8kHz~96kHz采样率&#xff0c;集成Δ-Σ调制器、数字抗混叠滤波器和高通滤波器&#xff0c;适用于高保真音频采集场景。 2. 核心特性 高精度&#xff1a;24位分辨率&#xff0c…...

Mysql8 忘记密码重置,以及问题解决

1.使用免密登录 找到配置MySQL文件&#xff0c;我的文件路径是/etc/mysql/my.cnf&#xff0c;有的人的是/etc/mysql/mysql.cnf 在里最后加入 skip-grant-tables重启MySQL服务 service mysql restartShutting down MySQL… SUCCESS! Starting MySQL… SUCCESS! 重启成功 2.登…...

Webpack性能优化:构建速度与体积优化策略

一、构建速度优化 1、​​升级Webpack和Node.js​​ ​​优化效果​​&#xff1a;Webpack 4比Webpack 3构建时间降低60%-98%。​​原因​​&#xff1a; V8引擎优化&#xff08;for of替代forEach、Map/Set替代Object&#xff09;。默认使用更快的md4哈希算法。AST直接从Loa…...

Unity UGUI Button事件流程

场景结构 测试代码 public class TestBtn : MonoBehaviour {void Start(){var btn GetComponent<Button>();btn.onClick.AddListener(OnClick);}private void OnClick(){Debug.Log("666");}}当添加事件时 // 实例化一个ButtonClickedEvent的事件 [Formerl…...