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

【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、缓冲区是什么&#xff1f; 2、为什么要有缓冲区&#xff1f; 3、怎么办&#xff1f; 我们先来复习一下&#xff0c;c语言对文件的操作&#xff1a; C默认会打开三个输入输出流&#xf…...

Unity WebGL使用nginx作反向代理处理跨域,一些跨域的错误处理(添加了反向代理的配置依旧不能跨域)

反向代理与跨域描述 什么是跨域&#xff1f; 跨域&#xff08;Cross-Origin Resource Sharing, CORS&#xff09;是指在浏览器中&#xff0c;当一个网页的脚本试图从一个域名&#xff08;协议、域名、端口&#xff09;请求另一个域名的资源时&#xff0c;浏览器会阻止这种请求…...

视频转文字免费的软件有哪些?6款工具一键把视频转成文字!又快又方便!

视频转文字免费的软件有哪些&#xff1f;在视频制作剪辑过程中&#xff0c;我们经常进行视频语音识别成字幕&#xff0c;帮助我们更好地呈现视频内容的观看和宣传&#xff0c;市场上有许多免费的视频转文字软件&#xff0c;可以快速导入视频&#xff0c;进行视频内音频的文字转…...

解决DHCP服务异常导致设备无法获取IP地址的方法

DHCP在网络环境中会自动为网络中的设备分配IP地址和其他关键网络参数&#xff0c;可以简化网络配置过程。但是&#xff0c;如果DHCP服务出现异常时&#xff0c;设备可能无法正常获取IP地址&#xff0c;会影响到网络通信。 本文讲述一些办法可以有效解决DHCP服务异常导致设备无法…...

Python机器学习模型的部署与维护:版本管理、监控与更新策略

&#x1f680; Python机器学习模型的部署与维护&#xff1a;版本管理、监控与更新策略 目录 &#x1f4bc; 模型版本管理 使用DVC进行数据和模型的版本控制&#xff0c;确保可复现性 &#x1f50d; 监控与评估 部署后的模型性能监控&#xff0c;使用Prometheus和Grafana进行实…...

免费送源码:Java+ssm+JSP+Ajax+MySQL SSM汽车租赁管理系统 计算机毕业设计原创定制

摘 要 信息化社会内需要与之针对性的信息获取途径&#xff0c;但是途径的扩展基本上为人们所努力的方向&#xff0c;由于站在的角度存在偏差&#xff0c;人们经常能够获得不同类型信息&#xff0c;这也是技术最为难以攻克的课题。针对汽车租赁信息管理等问题&#xff0c;对其进…...

Vivado viterbi decoder license

Viterbi Decoder 打卡以上链接 添加后next后&#xff0c; 会发送lic文件到邮件&#xff0c;vivado导入lic即可...

【FastAdmin】PHP的Trait机制:代码复用的新选择

PHP的Trait机制&#xff1a;代码复用的新选择 大家好&#xff0c;我是田辛老师。最近收到很多同学的私信&#xff0c;询问关于PHP中Trait机制的相关问题。今天&#xff0c;我们就来详细探讨一下这个强大的代码复用工具&#xff0c;以及它在ThinkPHP 5&#xff08;简称Tp5&…...

小红书制作视频如何去原视频音乐,视频如何去原声保留背景音乐?

在视频编辑、音乐制作或个人娱乐中&#xff0c;有时我们希望去掉视频中的原声&#xff08;如对话、解说等&#xff09;&#xff0c;仅保留背景音乐。这种处理能让观众更加聚焦于视频的氛围或节奏&#xff0c;同时也为创作者提供了更多创意空间。选择恰当的背景音乐&#xff0c;…...

netty之Netty使用Protobuf传输数据

前言 在netty数据传输过程中可以有很多选择&#xff0c;比如&#xff1b;字符串、json、xml、java对象&#xff0c;但为了保证传输的数据具备&#xff1b;良好的通用性、方便的操作性和传输的高性能&#xff0c;我们可以选择protobuf作为我们的数据传输格式。目前protobuf可以支…...

【力扣 | SQL题 | 每日四题】力扣2082, 2084, 2072, 2112, 180

四题都比较简单&#xff0c;可以直接秒。 1. 力扣2082&#xff1a;富有客户的数量 1.1 题目: 表&#xff1a; Store ------------------- | Column Name | Type | ------------------- | bill_id | int | | customer_id | int | | amount | int | -------------…...

快速了解Java中的15把锁!

目录 了解 总览 乐观锁 悲观锁 互斥锁和同步锁 公平锁 非公平锁 自旋锁 可重入锁&#xff08;递归锁&#xff09; ReadWriteLock读写锁 共享锁 独占锁 偏向锁 轻量级锁 重量级锁 锁优化 在 Java 中&#xff0c;锁是一种用于实现多线程之间同步和互斥的机制。 了…...

TypeScript 封装 Axios 1.7.7

随着Axios版本的不同&#xff0c;类型也在改变&#xff0c;以后怎么写类型&#xff1f; yarn add axios1. 封装Axios 将Axios封装成一个类&#xff0c;同时重新封装request方法 重新封装request有几个好处&#xff1a; 所有的请求将从我们定义的requet请求中发送&#xff…...

【数据结构】【链表代码】移除链表元素

移除链表元素 /*** Definition for singly-linked list.* struct ListNode {* int val;* struct ListNode *next;* };*/struct ListNode* removeElements(struct ListNode* head, int val) { // 创建一个虚拟头节点&#xff0c;以处理头节点可能被删除的情况 struct…...

作文-杭州游记

杭州的学习与游历 在这个风景如画的城市——杭州&#xff0c;学习信息学的日子如同西湖的水&#xff0c;清澈而又深邃。在这里&#xff0c;课堂与自然的交融、技术与文化的碰撞&#xff0c;构成了一幅独特的画卷。 学习之旅 信息学的课程不仅仅是对代码和算法的解析&#xff0…...

降压芯片TPS54821

降压芯片TPS54821 介绍 价格低廉&#xff0c;只需1.5元。是一个同步整流降压BUCK电路。MOS管内置。输入电压为4.5V至17V&#xff0c;输出电压为0.6V到15V&#xff0c;输出电流最大到8A。是QFN封装&#xff0c;焊接时有些许困难。得益于QFN封装&#xff0c;其引线电感非常的小…...

YOLO v1详解解读

&#x1f680; 在此之前主要介绍了YOLO v5源码的安装和使用&#xff08;YOLO v5安装教程&#xff09;&#xff0c;接下来将探索YOLO的实现原理&#xff0c;作为一个金典的单阶段目标检测算法&#xff0c;应该深度的理解它的构建思想&#xff1b;所以本系列文章将从LOVO v1出发到…...

【动态规划-最长公共子序列(LCS)】【hard】【科大讯飞笔试最后一题】力扣115. 不同的子序列

给你两个字符串 s 和 t &#xff0c;统计并返回在 s 的 子序列 中 t 出现的个数&#xff0c;结果需要对 10^9 7 取模。 示例 1&#xff1a; 输入&#xff1a;s “rabbbit”, t “rabbit” 输出&#xff1a;3 解释&#xff1a; 如下所示, 有 3 种可以从 s 中得到 “rabbit”…...

深入理解 JavaScript 中的 void`运算符和 yield*表达式

深入理解 JavaScript 中的 void 运算符和 yield* 表达式 在 JavaScript 中&#xff0c;void 运算符和 yield* 表达式是两个功能独特但常被忽视的运算符。本文将详细介绍它们的用法和应用场景&#xff0c;帮助您更好地理解和运用这两个运算符。 目录 void 运算符概述void 运算…...

第四节——从深层剖析指针(让你不再害怕指针)

文章目录 1. 字符指针变量剑指offer例题 2. 数组指针变量2.1 数组指针变量是什么&#xff1f;2.2 数组指针变量怎么初始化 3. ⼆维数组传参的本质代码实现 4. 函数指针变量4.1 函数指针变量的创建4.3 两段有趣的代码4.3.1 typedef 关键字 5. 函数指针数组的定义 1. 字符指针变量…...

观成科技:隐蔽隧道工具Ligolo-ng加密流量分析

1.工具介绍 Ligolo-ng是一款由go编写的高效隧道工具&#xff0c;该工具基于TUN接口实现其功能&#xff0c;利用反向TCP/TLS连接建立一条隐蔽的通信信道&#xff0c;支持使用Let’s Encrypt自动生成证书。Ligolo-ng的通信隐蔽性体现在其支持多种连接方式&#xff0c;适应复杂网…...

日语AI面试高效通关秘籍:专业解读与青柚面试智能助攻

在如今就业市场竞争日益激烈的背景下&#xff0c;越来越多的求职者将目光投向了日本及中日双语岗位。但是&#xff0c;一场日语面试往往让许多人感到步履维艰。你是否也曾因为面试官抛出的“刁钻问题”而心生畏惧&#xff1f;面对生疏的日语交流环境&#xff0c;即便提前恶补了…...

盘古信息PCB行业解决方案:以全域场景重构,激活智造新未来

一、破局&#xff1a;PCB行业的时代之问 在数字经济蓬勃发展的浪潮中&#xff0c;PCB&#xff08;印制电路板&#xff09;作为 “电子产品之母”&#xff0c;其重要性愈发凸显。随着 5G、人工智能等新兴技术的加速渗透&#xff0c;PCB行业面临着前所未有的挑战与机遇。产品迭代…...

解决Ubuntu22.04 VMware失败的问题 ubuntu入门之二十八

现象1 打开VMware失败 Ubuntu升级之后打开VMware上报需要安装vmmon和vmnet&#xff0c;点击确认后如下提示 最终上报fail 解决方法 内核升级导致&#xff0c;需要在新内核下重新下载编译安装 查看版本 $ vmware -v VMware Workstation 17.5.1 build-23298084$ lsb_release…...

06 Deep learning神经网络编程基础 激活函数 --吴恩达

深度学习激活函数详解 一、核心作用 引入非线性:使神经网络可学习复杂模式控制输出范围:如Sigmoid将输出限制在(0,1)梯度传递:影响反向传播的稳定性二、常见类型及数学表达 Sigmoid σ ( x ) = 1 1 +...

Caliper 配置文件解析:config.yaml

Caliper 是一个区块链性能基准测试工具,用于评估不同区块链平台的性能。下面我将详细解释你提供的 fisco-bcos.json 文件结构,并说明它与 config.yaml 文件的关系。 fisco-bcos.json 文件解析 这个文件是针对 FISCO-BCOS 区块链网络的 Caliper 配置文件,主要包含以下几个部…...

QT: `long long` 类型转换为 `QString` 2025.6.5

在 Qt 中&#xff0c;将 long long 类型转换为 QString 可以通过以下两种常用方法实现&#xff1a; 方法 1&#xff1a;使用 QString::number() 直接调用 QString 的静态方法 number()&#xff0c;将数值转换为字符串&#xff1a; long long value 1234567890123456789LL; …...

大学生职业发展与就业创业指导教学评价

这里是引用 作为软工2203/2204班的学生&#xff0c;我们非常感谢您在《大学生职业发展与就业创业指导》课程中的悉心教导。这门课程对我们即将面临实习和就业的工科学生来说至关重要&#xff0c;而您认真负责的教学态度&#xff0c;让课程的每一部分都充满了实用价值。 尤其让我…...

Java + Spring Boot + Mybatis 实现批量插入

在 Java 中使用 Spring Boot 和 MyBatis 实现批量插入可以通过以下步骤完成。这里提供两种常用方法&#xff1a;使用 MyBatis 的 <foreach> 标签和批处理模式&#xff08;ExecutorType.BATCH&#xff09;。 方法一&#xff1a;使用 XML 的 <foreach> 标签&#xff…...

推荐 github 项目:GeminiImageApp(图片生成方向,可以做一定的素材)

推荐 github 项目:GeminiImageApp(图片生成方向&#xff0c;可以做一定的素材) 这个项目能干嘛? 使用 gemini 2.0 的 api 和 google 其他的 api 来做衍生处理 简化和优化了文生图和图生图的行为(我的最主要) 并且有一些目标检测和切割(我用不到) 视频和 imagefx 因为没 a…...