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

【Linux】Linux 操作系统 - 19 , 重谈文件(三) ~ 学好 Linux 精髓是什么 , 缓冲区又是什么 ???【面试】

文章目录

  • Linux 精髓 --- 一切皆文件
    • 如何做到的 ??
  • 缓冲区
    • 一 、什么是缓冲区 ?
    • 二 、理解缓冲区
      • 0 .
      • 1 . 用户级语言层缓冲区和内核级文件缓冲区
      • 2 . 用户级语言层缓冲区在哪里呢 ??
      • 3 . 用户满足什么条件语言层缓冲区会刷新呢 ??
      • 4 . 再谈以上代码出现的现象的原因 ? (0. 中的代码)
      • 总结
  • 缓冲区的使用(要理解本质 , 重要 , 面试题)
  • 总结


Linux 精髓 — 一切皆文件


  在 Linux 中 , 一切皆文件 , 对没错 , 你没听错 !!! 是一切 .

  有人可能会想了 , Linux 系统不是还要管理硬件吗 ?? 能把硬件叫文件 ?? 怎么做到的 ??


先引出以下概念 :

在这里插入图片描述
前提铺垫

在这里插入图片描述


如何做到的 ??

在这里插入图片描述

  所以 , 真的是一切皆文件吗 ???

  对于进程一层而言 , 因为上层都是用的同一个函数指针 , 同名 , 同参类型的函数指针会屏蔽底层不同硬件的差异 , 通过函数指针指向不同的硬件 , 这样对于上层来说 , 无论访问什么都是通过 read , write 这样的系统调用来访问的 , 所以 , 对上层而言一切皆文件 !

  所以 , 要访问一个硬件 , 都是通过函数指针进行访问 !!!

这个模式相当于 C++ 中的多态 ! , struct file 这一层相当于基类 , 指向的不同的硬件相当于派生类 !

  • 源码
    在这里插入图片描述

缓冲区

一 、什么是缓冲区 ?

缓冲区 是内存空间的⼀部分。也就是说,在内存空间中预留了一定的存储空间,这些存储空间用来缓冲输人或输出的数据,这部分预留的空间就叫做缓冲区。缓冲区根据其对应的是输⼊设备还是输出设备,分为输入缓冲区和输出缓冲区 。

  简单来讲 : 缓冲区就是内存的一段空间 , 用来缓冲存储数据的 ! 提高效率的 !


二 、理解缓冲区

0 .


  这里先看一段代码 :

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <unistd.h>int main()
{	close(1);int fd = open("log.txt" , O_CREAT | O_WRONLY | O_TRUNC , 0666);// printf 默认向显示器打印 , 但是现在像 log.txt 打印printf("fd : %d\n" , fd);printf("Hello Linux!\n");printf("Hello Linux!\n");printf("Hello Linux!\n");//系统调用写内容const char* str = "I am Linux!\n";write(fd ,str , strlen(str));// 1 . 不用 close 关闭 fd , 后程序什么效果 ?//close(fd);// 2 . 用 close 关闭 fd , 后程序什么效果 ?	close(fd);return 0;
}
  • 不用
    在这里插入图片描述


  • 在这里插入图片描述

      ??? 为什么效果会不一样呢 ?? 到底什么原因 ?? 笔者介绍以下后 , 会再次谈 !


1 . 用户级语言层缓冲区和内核级文件缓冲区


  我们经常谈缓冲区 , 但是这个缓冲区究竟是指的什么呢 ??

  • 引出
    在这里插入图片描述

  • 具体谈
    在这里插入图片描述

  • 总结 , 我们平常谈的缓冲区到底是什么呢 ??

      我们平常说的缓冲区其实是 , 用户级语言层的缓冲区 !

      对于缓冲区我们要明白的 :

  • 缓冲区是有两个 : 1. 语言层的缓冲区 2 . 系统级的内核文件缓冲区

  • 当对显示器写入时(需要在显示器打印时) , 1 . 先把内容拷贝到标准库的语言层缓冲区中 2.当语言层缓冲区满足刷新条件时 , 再拷贝到内核级的文件缓冲区中 !

  • 当需要从硬件中读取时 , 会先把内容拷贝到内核文件缓冲区 , 满足刷新条件时 , 会拷贝到上层的语言层缓冲区 !

  • 总之 : 明白 , 缓冲区并不只有系统级 , 并且用户不能直接和系统打交道 , 中间需要语言层缓冲区的存在 !


2 . 用户级语言层缓冲区在哪里呢 ??


  目前 ,只知道在标准库中 , 但具体呢 ??

  注意观察 ,我们使用的 fprintf , fwrite 等都会有 FILE* 这样的东西 ?? 那 FILE 是什么呢 ??

在这里插入图片描述

  所以 , 对于这样的接口来说 , FILE* 是什么 ?

 FILE *fopen(const char *pathname, const char *mode);

FILE* 就是一个结构体指针 , 指向 FILE 这个结构体 , 每当有一个文件成功打开时 , C语言就会创建一个 FILE 的对象 ! 会存该文件的文件描述符 , 缓冲区等 ..

  • 源码验证

在这里插入图片描述


3 . 用户满足什么条件语言层缓冲区会刷新呢 ??

在这里插入图片描述
  当满足以上条件之一时 , 都会进行刷新 !!!


4 . 再谈以上代码出现的现象的原因 ? (0. 中的代码)

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <unistd.h>int main()
{	close(1);int fd = open("log.txt" , O_CREAT | O_WRONLY | O_TRUNC , 0666);// printf 默认向显示器打印 , 但是现在像 log.txt 打印printf("fd : %d\n" , fd);printf("Hello Linux!\n");printf("Hello Linux!\n");printf("Hello Linux!\n");//系统调用写内容const char* str = "I am Linux!\n";write(fd ,str , strlen(str));// 1 . 不用 close 关闭 fd , 后程序什么效果 ?//close(fd);// 2 . 用 close 关闭 fd , 后程序什么效果 ?	close(fd);return 0;
}

在这里插入图片描述


总结


  对于缓冲区这里 , 最终我们要掌握什么知识呢 ??

在这里插入图片描述

缓冲区的使用(要理解本质 , 重要 , 面试题)


  给出以下代码 , 观察现象 , 并回答为什么 ? 面试题

#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>int main()
{// 库函数 // 用向显示器打印的接口 printf("hello printf!\n"); // 默认向 1 - stdout 打印fprintf(stdout , "hello fprintf\n");const char* str = "hello fwrite\n";fwrite(str ,strlen(str) , 1 , stdout);// 系统调用 const char* s = "hello write\n";write( 1 , s , strlen(s));//创建子进程 fork();return 0;
}***********  用 gcc buf.c , 默认编译 , 生成 a.out 的可执行程序 *********** 解释一下 , 为什么第一次出现 4 条内容  ;  第二次会出现 7, 库函数内容出现均出现两次 , 系统调用却只出现一次呢   ??????? 第一次 : ./a.outhello printf!hello fprintfhello fwritehello write------------------
第二次 :./a.out > test.txt cat test.txt hello writehello printf!hello fprintfhello fwritehello printf!hello fprintfhello fwrite

在这里插入图片描述

  注 : 这个题要好好理解 , 很重要 !!!


总结

在这里插入图片描述

http://www.xdnf.cn/news/9418.html

相关文章:

  • 防火墙的访问控制
  • 【第1章 基础知识】1.4 开始学习HTML5
  • FLUX的实时显示
  • leetcode530.二叉搜索树的最小绝对差:递归中序遍历的差值追踪之道
  • t006-艺体培训机构业务管理系统
  • 上讯信息运维管理审计系统imo.php存在命令执行漏洞(CNVD-2025-07703)
  • Java基础打卡-集合2025.05.22
  • NHANES指标推荐:MQI
  • 2025吉林长春CCPC
  • C++STL之deque
  • 文件类型汇总
  • 机动与灵活的水上救援利器,冲锋舟
  • 深度解析 CC 攻击:原理、危害与防御策略​
  • C++将地址转换为字符串
  • 双特异性抗体的设计与开发
  • Java SapringBoot集成Redis存储Session,setAttribute会重置过期时间吗?怎么实现更新过期时间
  • Soft thinking和MixtureofInputs——大模型隐空间推理——本周论文速读
  • apk- 反编译apktools操作方法——请勿乱用-东方仙盟
  • Opigno LMS 3.2.7 安装操作记录
  • 32通道采集收发平台18G带宽直采
  • lcd-framebuffer驱动开发参考文章
  • 更新时间相差8个小时
  • Word 目录自动换行后错位与页码对齐问题解决教程
  • 某验4无感探针-js逆向
  • fabric 是一个开源框架,用于使用 AI 增强人类能力。它提供了一个模块化框架,用于使用一组可在任何地方使用的众包人工智能提示来解决特定问题
  • 仿真环境中机器人抓取与操作——感知与抓取
  • 通过实例来讲解MySQL锁机制
  • 智能的结构化觉醒:GraphRAG引领AI进入关系世界
  • JDK21深度解密 Day 6:ZGC与内存管理进化
  • Flink Table API 编程入门实践