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

文件系统调用(下) ─── linux第18课

        文件描述符就是从0开始的小整数。当我们打开文件时,操作系统在内存中要创建相应的数据结构来 描述目标文件。于是就有了file结构体。表示一个已经打开的文件对象。而进程执行open系统调用,所以必须让进程和文件关联起来。每个进程都有一个指针*files, 指向一张表files_struct,该表最重要的部分就是包涵一个指针数组,每个元素都是一个指向打开文件的指针!

        文件描述符就是该数组的下标。所以,只要拿着文件 描述符,就可以找到对应的文件

原来我在博客中也提过,linux下一切皆文件, 如何理解呢?

linux下一切皆文件

        硬盘 , 网卡, 键盘,显示器等外设都是文件?

  • 一切皆文件" 是 Linux 的核心设计哲学,在进程角度, 将系统中的各种资源抽象为文件

  • 通过统一的文件接口,可以方便地访问和操作硬件设备、进程信息、网络套接字等资源。

VFS 虚拟文件系统 (多态)

  • 统一都有struct file ,上层都以 struct file 形式访问
  • 将不同设备用相同的结构体 struct file 管理起来,从进程角度(上层) ,就是一切皆文件

如何用结构体统一管理呢? 尤其是不同设备的调用方法不同

        因为linux是C语言写的,也就是struct file 中不能包含成员函数 , 所以linux在struct file中 ,使用了函数指针 , 对应了该设备的具体调用函数.

        用函数指针屏蔽了底层的差异 , 读写网卡 /键盘等 , 上层就不关心具体方法了.

        

        系统调用(sysem call)在内部就直接调用 ,对应的函数指针  例如: 

     int fd1 = open("open.txt" , O_RDWR|O_CREAT , 0666);
     if(fd1 < 0)
     {
          perror("open");
         return 1;
     }
 
     const char* message ="hello linux\n";
     write(fd1, message, strlen(message));在文件open.txt中写入
     write(1,message ,strlen(message));  在屏幕上写入
 
     close(fd1);

        这两种写入, write通过文件描述符(fd)找到对应的 struct file 调用对应的函数指针即可,并不关心是向磁盘中写入 ,还是向显示屏中写入.

struct file中的一个指针指向 函数指针表

I/O的基本过程

1.文件的内核缓冲区

内核缓冲区存在的意义:

        外设的io操作太慢了,为了提高io效率,每个文件都有一个内核缓冲区.

文件的系统调用本质:

  • 写入 write: 将数据从用户拷贝到 文件的内核缓冲区.(先不刷新到对应的磁盘文件)
  • 读入 read: 将磁盘文件加载到 文件的内核缓冲区,再拷贝给用户.

文件的struct file 中包含 文件的内核缓冲区的指针

2.重定向

文件描述符的分配规则

        文件描述符的分配规则:在files_struct数组当中,找到当前没有被使用的最小的一个下标,作为新的文件描述符。

include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
 
int main()
{
 close(1);
 int fd = open("myfile", O_WRONLY|O_CREAT, 00644);
 if(fd < 0){
     perror("open");
     return 1;
 }
 printf("fd: %d\n", fd);
 fflush(stdout);
 
 close(fd);
 exit(0);
}

        我们发现,本来应该输出到显示器上的内容,输出到了文件 myfile 当中,其中,fd=1。这种现象叫做输出 重定向。

        常见的重定向有:>, >>, <

那重定向的本质是什么呢?

        我们原来讲过   从上层看, 文件描述符(fd)是 访问硬件的唯一方式

        printf是C库当中的IO函数,一般往 stdout 中输出,但是stdout底层访问文件的时候,找的还是fd:1, 但此时,fd:1 下标所表示内容,已经变成了myfile的地址,不再是显示器文件的地址,所以,输出的任何消息都会往文件中写 入,进而完成输出重定向。

输出重定向

dup2让newfd成为oldfd的拷贝,此时两个file* 都指向 同一个struct file ,会发生引用计数.

dup2(fd ,1) 

重定向和追加重定向

两者打开文件open函数的flags不同

  •         重定向的flags: O_CREAT | O_WRONLY
  •         追加重定向的flags:O_CREAT | O_WRONLY |O_APPEND

相关文章:

  • 【redis】string应用场景:缓存功能和计数功能
  • UVa12303 Composite Transformations
  • c#客户端请求 Server-Sent Events
  • 音视频开发面试准备
  • Python组合数据类型(二)
  • Python字典,集合
  • Linux 网络:skb 数据管理
  • WEB实时推送消息的7种方式
  • 开发常用软件
  • C++设计模式-抽象工厂模式:从原理、适用场景、使用方法,常见问题和解决方案深度解析
  • Python 构建Flask网页端远程控制Windows系统功能
  • 基于Ollama平台部署的Qwen大模型实现聊天机器人
  • 计算机考研C语言
  • Docker搭建Redis哨兵模式【一主两从三哨兵】
  • 《TCP/IP网络编程》学习笔记 | Chapter 17:优于 select 的 epoll
  • 面试之《commonjs,requirejs和es6 Module的区别》
  • Photo Works在线图片编辑器:一键修复老照片,轻松焕新记忆
  • java-单列模式-final-枚举
  • 「 DelegateUI 」Ant-d 风格的 Qt Qml UI 套件
  • 瑞芯微RK3576(1)-硬件设计
  • 以色列计划“占领加沙”,特朗普下周中东行结束之际将是“机会窗口”
  • 为什么有的人闻到烟味,会咳嗽、胸闷?别再伤害身边的人
  • 《探秘海昏侯国》数字沉浸特展亮相首届江西文化旅游产业博览交易会
  • 江西德安回应“义门陈遗址建筑被没收”:将交由规范的义门陈相关社会组织管理
  • 量子传感新技术“攻克”退相干难题
  • 中国农业国际交流协会会长王守聪失联已逾半年,协会启动罢免