【Linux 】文件描述符fd、重定向、缓冲区(超详解)
目录
编辑 系统接口进行文件访问
open 接口介绍
文件描述符fd
重定向
缓冲区
1、缓冲区是什么?
2、为什么要有缓冲区?
3、怎么办?
我们先来复习一下,c语言对文件的操作:
C默认会打开三个输入输出流,分别是stdin, stdout, stderr
1 #include<stdio.h>2 3 int main()4 {5 FILE *fp=fopen("log.txt","w");6 if(fp==NULL)7 {8 perror("error!");9 return 1;10 }11 fprintf(fp,"hello,%d,%s\n",10,"sxh");12 fclose(fp);13 return 0;14 }
系统接口进行文件访问
操作文件,除了上述C接口(当然,C++也有接口,其他语言也有),我们还可以采用系统接口来进行文件访问;
#include<stdio.h>#include<string.h>#include<sys/types.h>#include<sys/stat.h>#include<fcntl.h>#include<unistd.h>int main(){umask(0);int fd =open("log.txt",O_WRONLY | O_CREAT |O_TRUNC,0666);if(fd<0){ perror("open");return 1;}//const char *message ="hello Linux!\n";const char * message ="aaaa\n";write(fd,message,strlen(message));close(fd);}
open("log.txt",O_WRONLY | O_CREAT |O_TRUNC,0666);:以写方式打开,不存在就创建,存在就先清空!相当于c语言中的 “w” 方式;
open 接口介绍
open man 2 open
#includ e <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>int open(const char *pathname, int flags);
int open(const char *pathname, int flags, mode_t mode)
int creat(const char *pathname, mode_t mode);pathname:要打开或创建的目标文件
flags: 打开文件时,可以传入多个参数选项,用下面的一个或者多个常量进行“或”运算,构成; 常见的参数有:
O_RDONLY: 只读打开
O_WRONLY: 只写打开
O_CREAT : 若文件不存在,则创建它。需要使用mode选项,来指明新文件的访问权限
O_APPEND: 追加写mode: mode 只有 当 在 flags 中使用 O_CREAT 时才有效 , 否则被忽略.
返回值:
成功:新打开的文件描述符
失败:-1
文件描述符fd
我们通过系统调用I/O打开一个文件的返回值,就是文件描述符:
int fd = open("log.txt",O_WRONLY | O_CREAT |O_TRUNC,0666);
这里fd就是log.txt的文件描述符;
如果我们同时打开三个文件,并把这三个文件的文件描述符打印出来,会发现:
文件描述符是从3开始的,那0、1、2呢?
Linux进程默认情况下会有3个缺省打开的文件描述符:分别是标准输入0, 标准输出1, 标准错误2.
0,1,2对应的物理设备一般是:键盘,显示器,显示器


根据上述的图,我们可以知道:
open干什么?
1、创建file
2、开辟文件缓冲区的空间,加载文件数据(延后)
3、查看进程的文件描述符表
4、file地址,填入对应的表下标中
5、返回下标
重定向
看一下下面的代码:
1 #include<stdio.h>2 #include<sys/types.h>3 #include<sys/stat.h>4 #include<fcntl.h>5 #include<unistd.h>6 #include<string.h>7 #include<stdlib.h>8 const char *filename="log.txt";9 10 int main()11 {12 //close(0);13 close(1);14 //close(2);15 int fd =open(filename,O_CREAT | O_WRONLY | O_TRUNC,0666);16 if(fd<0)17 {18 perror("open");19 return 1;20 }21 printf("printf,fd:%d\n",fd);22 fprintf(stdout,"fprintf,fd:%d\n",fd);23 24 fflush(stdout);25 26 27 close(fd);28 return 0;29 30 }
先看现象:
1、如果我们关闭的是0:打印出来的log.txt的文件描述符是0;关闭的是2,则打印出来的文件描述符是2;关闭的是1,则不会显示出来;因为文件描述符1表示的是显示器,而我们把显示器关掉了自然打印不出来;
2、我们会在log.txt中打印出printf和fprintf的内容:

现象解释:
文件描述符规则:查看自己的文件描述表,分配最小的没有使用的文件描述符;
由于我们把显示器给关掉了,那么文件描述符1就是最小的没有使用的,这样log.txt就会被分配1为文件描述符;这其实就是一个重定向操作;
看下面的图:
一开始fd_array[1]指向的是显示器,由于close(1),加上open log.txt这样fd_array[1]指向的就是log.txt;
因为重定向的本质是在内核中改变文件描述符特点下标的内容,与上层无关;
fprintf()/printf() --->stdout --->struct FILE --->stdout ---->_fileno ==1;
所以fprintf()/printf() 看的就是_fileno ==1;由于重定向后log.txt的fd为1 ,自然fprintf()/printf()的内容打印到log.txt中;

如果我们一直用这种手动重定向的方式,比较麻烦;可以用系统调用:dup2()

看一下代码:
1 #include<stdio.h>2 #include<sys/types.h>3 #include<sys/stat.h>4 #include<fcntl.h>5 #include<unistd.h>6 #include<string.h>7 #include<stdlib.h>8 const char *filename="log.txt";9 10 int main()11 {12 int fd = open(filename,O_CREAT | O_WRONLY | O_TRUNC,0666);13 //dup2(fd,1);14 15 printf("hello world,fd:%d\n",fd);16 fprintf(stdout,"hello world\n");17 fflush(stdout);18 close(fd);19 return 0;20 }
上述的代码运行结果:会直接打印到显示器上;

如果把dup2(fd,1);复原:显示器上不会显示,而是在log.txt上显示

其实本质就是将fd覆盖1 指向下标的内容;

缓冲区
1、缓冲区是什么?
缓冲区就是一段内存空间
2、为什么要有缓冲区?
给上层提供高效的IO体验,间接提高整体效率
3、怎么办?
a、刷新策略
1、立即刷新 fflush(stdout)(c语言的刷新)、fsync(fd)(系统调用的刷新)
2、行刷新 (显示器)
3、全缓冲 (缓冲区写满,才刷新,普通文件)
b、特殊情况
进程退出,系统会自动刷新
强制刷新
相关文章:
【Linux 】文件描述符fd、重定向、缓冲区(超详解)
目录 编辑 系统接口进行文件访问 open 接口介绍 文件描述符fd 重定向 缓冲区 1、缓冲区是什么? 2、为什么要有缓冲区? 3、怎么办? 我们先来复习一下,c语言对文件的操作: C默认会打开三个输入输出流…...
Unity WebGL使用nginx作反向代理处理跨域,一些跨域的错误处理(添加了反向代理的配置依旧不能跨域)
反向代理与跨域描述 什么是跨域? 跨域(Cross-Origin Resource Sharing, CORS)是指在浏览器中,当一个网页的脚本试图从一个域名(协议、域名、端口)请求另一个域名的资源时,浏览器会阻止这种请求…...
视频转文字免费的软件有哪些?6款工具一键把视频转成文字!又快又方便!
视频转文字免费的软件有哪些?在视频制作剪辑过程中,我们经常进行视频语音识别成字幕,帮助我们更好地呈现视频内容的观看和宣传,市场上有许多免费的视频转文字软件,可以快速导入视频,进行视频内音频的文字转…...
解决DHCP服务异常导致设备无法获取IP地址的方法
DHCP在网络环境中会自动为网络中的设备分配IP地址和其他关键网络参数,可以简化网络配置过程。但是,如果DHCP服务出现异常时,设备可能无法正常获取IP地址,会影响到网络通信。 本文讲述一些办法可以有效解决DHCP服务异常导致设备无法…...
Python机器学习模型的部署与维护:版本管理、监控与更新策略
🚀 Python机器学习模型的部署与维护:版本管理、监控与更新策略 目录 💼 模型版本管理 使用DVC进行数据和模型的版本控制,确保可复现性 🔍 监控与评估 部署后的模型性能监控,使用Prometheus和Grafana进行实…...
免费送源码:Java+ssm+JSP+Ajax+MySQL SSM汽车租赁管理系统 计算机毕业设计原创定制
摘 要 信息化社会内需要与之针对性的信息获取途径,但是途径的扩展基本上为人们所努力的方向,由于站在的角度存在偏差,人们经常能够获得不同类型信息,这也是技术最为难以攻克的课题。针对汽车租赁信息管理等问题,对其进…...
Vivado viterbi decoder license
Viterbi Decoder 打卡以上链接 添加后next后, 会发送lic文件到邮件,vivado导入lic即可...
【FastAdmin】PHP的Trait机制:代码复用的新选择
PHP的Trait机制:代码复用的新选择 大家好,我是田辛老师。最近收到很多同学的私信,询问关于PHP中Trait机制的相关问题。今天,我们就来详细探讨一下这个强大的代码复用工具,以及它在ThinkPHP 5(简称Tp5&…...
小红书制作视频如何去原视频音乐,视频如何去原声保留背景音乐?
在视频编辑、音乐制作或个人娱乐中,有时我们希望去掉视频中的原声(如对话、解说等),仅保留背景音乐。这种处理能让观众更加聚焦于视频的氛围或节奏,同时也为创作者提供了更多创意空间。选择恰当的背景音乐,…...
netty之Netty使用Protobuf传输数据
前言 在netty数据传输过程中可以有很多选择,比如;字符串、json、xml、java对象,但为了保证传输的数据具备;良好的通用性、方便的操作性和传输的高性能,我们可以选择protobuf作为我们的数据传输格式。目前protobuf可以支…...
【力扣 | SQL题 | 每日四题】力扣2082, 2084, 2072, 2112, 180
四题都比较简单,可以直接秒。 1. 力扣2082:富有客户的数量 1.1 题目: 表: Store ------------------- | Column Name | Type | ------------------- | bill_id | int | | customer_id | int | | amount | int | -------------…...
快速了解Java中的15把锁!
目录 了解 总览 乐观锁 悲观锁 互斥锁和同步锁 公平锁 非公平锁 自旋锁 可重入锁(递归锁) ReadWriteLock读写锁 共享锁 独占锁 偏向锁 轻量级锁 重量级锁 锁优化 在 Java 中,锁是一种用于实现多线程之间同步和互斥的机制。 了…...
TypeScript 封装 Axios 1.7.7
随着Axios版本的不同,类型也在改变,以后怎么写类型? yarn add axios1. 封装Axios 将Axios封装成一个类,同时重新封装request方法 重新封装request有几个好处: 所有的请求将从我们定义的requet请求中发送ÿ…...
【数据结构】【链表代码】移除链表元素
移除链表元素 /*** Definition for singly-linked list.* struct ListNode {* int val;* struct ListNode *next;* };*/struct ListNode* removeElements(struct ListNode* head, int val) { // 创建一个虚拟头节点,以处理头节点可能被删除的情况 struct…...
作文-杭州游记
杭州的学习与游历 在这个风景如画的城市——杭州,学习信息学的日子如同西湖的水,清澈而又深邃。在这里,课堂与自然的交融、技术与文化的碰撞,构成了一幅独特的画卷。 学习之旅 信息学的课程不仅仅是对代码和算法的解析࿰…...
降压芯片TPS54821
降压芯片TPS54821 介绍 价格低廉,只需1.5元。是一个同步整流降压BUCK电路。MOS管内置。输入电压为4.5V至17V,输出电压为0.6V到15V,输出电流最大到8A。是QFN封装,焊接时有些许困难。得益于QFN封装,其引线电感非常的小…...
YOLO v1详解解读
🚀 在此之前主要介绍了YOLO v5源码的安装和使用(YOLO v5安装教程),接下来将探索YOLO的实现原理,作为一个金典的单阶段目标检测算法,应该深度的理解它的构建思想;所以本系列文章将从LOVO v1出发到…...
【动态规划-最长公共子序列(LCS)】【hard】【科大讯飞笔试最后一题】力扣115. 不同的子序列
给你两个字符串 s 和 t ,统计并返回在 s 的 子序列 中 t 出现的个数,结果需要对 10^9 7 取模。 示例 1: 输入:s “rabbbit”, t “rabbit” 输出:3 解释: 如下所示, 有 3 种可以从 s 中得到 “rabbit”…...
深入理解 JavaScript 中的 void`运算符和 yield*表达式
深入理解 JavaScript 中的 void 运算符和 yield* 表达式 在 JavaScript 中,void 运算符和 yield* 表达式是两个功能独特但常被忽视的运算符。本文将详细介绍它们的用法和应用场景,帮助您更好地理解和运用这两个运算符。 目录 void 运算符概述void 运算…...
第四节——从深层剖析指针(让你不再害怕指针)
文章目录 1. 字符指针变量剑指offer例题 2. 数组指针变量2.1 数组指针变量是什么?2.2 数组指针变量怎么初始化 3. ⼆维数组传参的本质代码实现 4. 函数指针变量4.1 函数指针变量的创建4.3 两段有趣的代码4.3.1 typedef 关键字 5. 函数指针数组的定义 1. 字符指针变量…...
Cursor实现用excel数据填充word模版的方法
cursor主页:https://www.cursor.com/ 任务目标:把excel格式的数据里的单元格,按照某一个固定模版填充到word中 文章目录 注意事项逐步生成程序1. 确定格式2. 调试程序 注意事项 直接给一个excel文件和最终呈现的word文件的示例,…...
大话软工笔记—需求分析概述
需求分析,就是要对需求调研收集到的资料信息逐个地进行拆分、研究,从大量的不确定“需求”中确定出哪些需求最终要转换为确定的“功能需求”。 需求分析的作用非常重要,后续设计的依据主要来自于需求分析的成果,包括: 项目的目的…...
Cesium1.95中高性能加载1500个点
一、基本方式: 图标使用.png比.svg性能要好 <template><div id"cesiumContainer"></div><div class"toolbar"><button id"resetButton">重新生成点</button><span id"countDisplay&qu…...
从零开始打造 OpenSTLinux 6.6 Yocto 系统(基于STM32CubeMX)(九)
设备树移植 和uboot设备树修改的内容同步到kernel将设备树stm32mp157d-stm32mp157daa1-mx.dts复制到内核源码目录下 源码修改及编译 修改arch/arm/boot/dts/st/Makefile,新增设备树编译 stm32mp157f-ev1-m4-examples.dtb \stm32mp157d-stm32mp157daa1-mx.dtb修改…...
EtherNet/IP转DeviceNet协议网关详解
一,设备主要功能 疆鸿智能JH-DVN-EIP本产品是自主研发的一款EtherNet/IP从站功能的通讯网关。该产品主要功能是连接DeviceNet总线和EtherNet/IP网络,本网关连接到EtherNet/IP总线中做为从站使用,连接到DeviceNet总线中做为从站使用。 在自动…...
Android Bitmap治理全解析:从加载优化到泄漏防控的全生命周期管理
引言 Bitmap(位图)是Android应用内存占用的“头号杀手”。一张1080P(1920x1080)的图片以ARGB_8888格式加载时,内存占用高达8MB(192010804字节)。据统计,超过60%的应用OOM崩溃与Bitm…...
优选算法第十二讲:队列 + 宽搜 优先级队列
优选算法第十二讲:队列 宽搜 && 优先级队列 1.N叉树的层序遍历2.二叉树的锯齿型层序遍历3.二叉树最大宽度4.在每个树行中找最大值5.优先级队列 -- 最后一块石头的重量6.数据流中的第K大元素7.前K个高频单词8.数据流的中位数 1.N叉树的层序遍历 2.二叉树的锯…...
Web 架构之 CDN 加速原理与落地实践
文章目录 一、思维导图二、正文内容(一)CDN 基础概念1. 定义2. 组成部分 (二)CDN 加速原理1. 请求路由2. 内容缓存3. 内容更新 (三)CDN 落地实践1. 选择 CDN 服务商2. 配置 CDN3. 集成到 Web 架构 …...
Mysql中select查询语句的执行过程
目录 1、介绍 1.1、组件介绍 1.2、Sql执行顺序 2、执行流程 2.1. 连接与认证 2.2. 查询缓存 2.3. 语法解析(Parser) 2.4、执行sql 1. 预处理(Preprocessor) 2. 查询优化器(Optimizer) 3. 执行器…...
MySQL 8.0 事务全面讲解
以下是一个结合两次回答的 MySQL 8.0 事务全面讲解,涵盖了事务的核心概念、操作示例、失败回滚、隔离级别、事务性 DDL 和 XA 事务等内容,并修正了查看隔离级别的命令。 MySQL 8.0 事务全面讲解 一、事务的核心概念(ACID) 事务是…...
