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

文件标识符fd

1.用c语言打开一个文件

#include<stdio.h>    
    
int main()    
{    
  FILE* fp=fopen("log.txt","w");    
  if(fp==NULL)    
  {    
    perror("fopen");    
    return 1;    
  }    
  fclose(fp);    
                                                                                                                                                             
  return 0;    
}    

我们用“w"的方式打开log.txt文件,如果这个文件不存在,就创建这个文件,如果文件存在,就把这个文件内容清空然后打开

打开文件的本质是进程打开文件,文件没有被打开时,在磁盘中

一个进程可以打开多个文件,那么操作系统中肯定存在大量被打开的文件,那么怎么对这些文件管理呢?

2.文件管理

文件=属性+内容

文件->磁盘->外设->硬件,所以向文件写入本质上是向硬件中写入,但是用户们没有权力直接访问硬件,所以要通过操作系统访问硬件,我们用的C/C++文件操作本质上都是对系统调用接口的封装

1.系统调用的文件操作

  #include<stdio.h> 
  #include<unistd.h>
  #include<sys/types.h>    
  #include<sys/stat.h>    
  #include<fcntl.h>    
      
  int main()    
  {    
    umask(0);//修改文件权限默认掩码    
    //system call    
    int fd=open("log.txt",O_WRONLY|O_CREAT,0666);    
    if(fd<0)    
    {    
      perror("fd");    
      return 1;    
    }                                                                                                                                                        
  close(fd);    
    return 0;    
  }  

对于open函数

#include <fcntl.h>

int open(const char *pathname, int flags, ...);

pathname:表示指向包含文件名的字符串指针,flags表示以不同的方式打开这个文件,比如:

  • O_RDONLY:以只读方式打开文件。
  • O_WRONLY:以只写方式打开文件。
  • O_RDWR:以读写方式打开文件。
  • O_CREAT:如果文件不存在则创建它。
  • O_TRUNC:如果文件已存在且成功打开,则将其长度截断为 0。
  • O_APPEND:写入时将数据追加到文件末尾。
  • O_EXCL:与 O_CREAT 一起使用,如果文件已存在则 open 调用失败。
  • O_NONBLOCK:以非阻塞模式打开文件。
  • O_SYNC:所有写操作都应同步到存储设备。

...:如果我们第二个参数使用了O_CREAT,那么第三个参数表示创建文件的权限,它通常与umask相结合来确定文件的最终权限,比如umask为0,第三个参数设置成0666,表示文件权限是rw-rw-rw-,

open函数失败时返回-1,成功时返回一个非负的文件描述符;

2.fd理解

什么是fd呢?

文件描述符fd本质上是文件映射关系的下标

我们使用系统调用函数open打开文件时,首先我们把进程加载到内存中,进程的task_struct中有一个files指针,用来指向files_struct结构体,files_struct结构体是代表进程打开文件信息的数据结构,被打开的文件也会在内存中加载对应的file结构体,每一个被打开的文件在内存中有对应的struct file,同时开辟的有文件缓存区,然后文件内容从磁盘上拷贝到文件缓冲区中,然后被打开的文件属性保存到file结构体中,这样就可以对文件进行管理了,每一个file结构体对应的fd_array数组的下标,就是文件标识符fd,用来管理这个文件,然后我们获取到文件标识符fd,可以对文件进行写入,修改,

open的作用

  • 创建file
  • 开辟文件缓冲区的空间
  • 查进程的文件标识符
  • file地址,填入对应的表下标中
  • 返回下标

3.fd的0,1,2

我们理解了,每一个文件标识符标识一个文件,那么fd 0 1 2 的文件默认被打开了,是什么文件呢?

0:标准输入 键盘

1:标准输出 显示器

2:标准错误 显示器

那么为什么这些硬件也叫做文件呢?如何理解linux一切皆文件

对于硬件,我们有对应的驱动管理,然后用虚拟文件管理封装成文件,就可以对文件进行管理了,

4.C语言的文件操作

所有c语言的文件操作函数,本质都是对系统调用的封装,

fclose,fopen,fread,fwrite这些库函数的类型都是FILE*,FILE是c语言提供的一个结构体类型,封装了fd,才可以对文件进行操作,

C语言为什么要封装呢?

因为不同系统,对应的系统调用接口也不同,那么写出的代码不具备跨平台性,而C语言想要具有跨平台性,就要对不同系统的系统函数进行封装,


http://www.kler.cn/news/308587.html

相关文章:

  • 嵌入式Linux学习笔记(5)-进程间常见通讯方式(c语言实现)
  • 09_Python流程控制_分支
  • win10怎么配置dnat规则,访问win10的网口A ip的6443端口,映射到1.1.1.1的6443端口去
  • Android 源码集成可卸载 APP
  • go多线程
  • python-在PyCharm中使用PyQt5
  • 【C++】多态详解
  • mysql学习教程,从入门到精通,SQL IN BETWEEN 运算符(13)
  • 基于STM32F407ZGT6——看门狗
  • new/delete和malloc/free到底有什么区别
  • docker镜像结构
  • 代码随想录:动态规划4-5
  • Java技术深度探索:高并发场景下的线程安全与性能优化
  • java面试题-Sql 语句的执行顺序
  • 【SOP】使用MMDeploy将MMAction2的模型转换为TensorRT
  • 二叉树的前中后序遍历(递归法)( 含leetcode上三道【前中后序】遍历题目)
  • java-lambda-常用方法总结汇总
  • 【乐企】旅客运输发票接口实现
  • 第159天:安全开发-Python-协议库爆破FTPSSHRedisSMTPMYSQL等
  • 持续集成与持续交付CI/CD
  • TDengine 首席架构师肖波演讲整理:探索新型电力系统的五大关键场景与挑战
  • CentOS7下安装Ruby3.2.4的实施路径
  • LeetCode_sql_day26(184,1549,1532,1831)
  • ubuntu系统服务器离线安装python包
  • 力扣(leetcode)每日一题 2848 与车相交的点
  • 7天速成前端 ------学习日志 (继苍穹外卖之后)
  • Spire.PDF for .NET【页面设置】演示:为 PDF 添加背景颜色或背景图像
  • python压缩图片的代码
  • 《锐捷AP 胖模式配置示例》
  • UiBot教程:实现复杂流程图的高效方法