Linux 之 【文件】(文件共识原理、open、close、访问文件的本质、文件描述符)

目录

1.文件共识原理

2.文件系统调用接口

2.1open

[2.2 close](#2.2 close)

3.访问文件的本质

4.文件描述符


1.文件共识原理

  • 文件 = 内容 + 属性
  • 文件分为 打开的文件 和 未打开的文件
  • 文件是由进程打开的,学习打开的文件,本质上是学习进程与文件之间的关系
  • 没打开的文件存储在磁盘上,学习未打开的文件,主要是学习如何存储文件以让用户能够快速找到文件从而进行增删查改的操作
  • 文件要被打开,那么文件一定要先加载到内存当中
  • 进程 : 打开的文件 = 1 : n 也就是说,一个进程可以打开多个文件
  • 操作系统通过先描述再组织的原理管理大量打开的文件:在内核中,一个被打开的文件都有自己的文件打开对象,包含着文件的许多属性。

2.文件系统调用接口

用户访问磁盘文件肯定需要访问磁盘,而用户只能通过操作系统访问磁盘,所以用户访问磁盘文件的函数或封装或直接使用了系统调用

2.1open

2参数的open函数显然是3参数open函数的子集,所以这里只介绍3参数的open函数

(1)pathname

pathname: 文件路径字符串

要么是绝对路径 (如 /home/user/file.txt),从根目录开始

要么只是相对路径 (./file.txt 或 ../file.log),相对于当前工作目录(CWD)。

(2)flags

flags: 打开标志,即用户以什么方式打开

  • O_RDONLY:只读
  • O_WRONLY:只写
  • O_RDWR:读写
  • O_CREAT:不存在则创建
  • O_TRUNC:存在则清空
  • O_APPEND:追加模式
  • O_EXCL:与O_CREAT搭配,文件存在则失败
  • O_NONBLOCK:非阻塞
    打开方式是用宏定义的,这里通过宏定义的标志位以比特位方式组合传参的
    一个int类型有32个比特位,每一位都可以充当一个标志位,从而进行传参

O_WRONLY | O_CREATE 从头开始覆盖写,不清空

常用组合:

O_RDONLY //只读
O_WRONLY | O_CREAT | O_TRUNC //不存在就创建,存在就清空从头开始写
O_WRONLY | O_CREAT | O_APPEND //不存在就创建,存在就从文件末尾开始写

(3)mode

mode:创建文件时的权限**(八进制)**,仅 O_CREAT 时有效

Linux下使用系统调用open创建不存在的文件时必须指定权限,否则权限就是乱码

成功创建合规的文件

可以是局部使用系统调用umask修改权限掩码,使得所创建的文件的权限为指定权限

(4)返回值

成功:返回文件描述符(fd) (非负整数) 失败:返回 -1,并设置 errno

(5)C语言fopen与open 的联系

2.2 close

参数fd指的是要关闭的文件描述符

close执行成功:返回 0

close执行失败:返回 -1,并设置 errno

3.访问文件的本质

Linux下:

  1. 进程拥有自己的描述对象 task_struct ,这其中包含一个 struct files_struct* 的指针,该指针用来指向 struct files_struct 结构体,该结构体中包含一个指针数组 struct file* fd_array[],该数组又叫做文件描述符表,每个进程有独立的 fd_array[]
  2. 操作系统为每一个打开的文件创建一个 struct file 结构体,用来描述打开的文件的信息,struct file 包含引用计数
  3. 进程与文件之间的联系是 task_struct 与 struct file 之间的联系,文件描述符存储着 struct file的指针,所以 task_struct 与 struct file 通过文件描述符进行联系
  4. task_struct → files_struct → fd_array[] → struct file
  5. 文件描述符唯一确定某个打开的文件,文件描述符的本质就是指针数组的下标

4.文件描述符

(1)概念

在进程中每打开一个文件,都会创建有相应的文件描述信息struct file,这个结构体指针被添加在pcb的struct files_struct中,以数组的形式进行管理,随即向用户返回数组的下标作为文件描述符,用于操作文件

(2)文件描述符的本质

文件描述符的本质就是指针数组的下标

(3)文件描述符的分配规则

最小未使用文件描述符策略:从下标0开始顺序查找没有被使用的数组位置,该下标就是新文件的文件描述符

进程运行起来后,自动打开标准输入文件(0:键盘文件)标准输出文件(1:显示器文件)标准错误文件(2:显示器文件),这是操作系统的特性,是程序员写代码的天然需要,是广大程序语言所必须遵守的规则

那么,在标准流没有被关闭或重定向的情况下,新打开的文件描述符通常从3开始
因为 Linux下访问文件只认文件描述符,所以C语言的FILE结构体一定封装了文件描述符

stdout(1)和stderr(2) 默认指向显示器文件,是两个独立的文件描述符,对应不同的struct file对象

printf 向标准输出文件(显示器文件)打印内容,文件指针是stdout,文件描述符是 1

C++中的文件流的本质与FILE结构体是类似的,直接或间接的包含了文件描述符

相关推荐
skywalk81632 小时前
快速启动wiki维基百科服务器 kiwix-serve --port=8080 wikipedia_zh_physics_mini_2025-12.zim
linux·运维·服务器·wiki
那些年的笔记2 小时前
Ubuntu22.04 英文界面转成中文界面
linux·运维·服务器
新兴AI民工2 小时前
【Linux内核七】进程管理模块:进程调度管理器sched_class
linux·服务器·linux内核
快乐的划水a2 小时前
上下文简析
linux·运维·服务器
HABuo2 小时前
【linux进程控制(一)】进程创建&退出-->fork&退出码详谈
linux·运维·服务器·c语言·c++·ubuntu·centos
EndingCoder2 小时前
高级类型:联合类型和类型别名
linux·服务器·前端·ubuntu·typescript
2301_765715142 小时前
Linux中组合使用多个命令的技巧与实现
linux·运维·chrome
想唱rap2 小时前
MySQL内置函数
linux·运维·服务器·数据库·c++·mysql
Jet_582 小时前
Ubuntu 桌面版 Wireshark 抓包权限不足问题解决指南
linux·ubuntu·wireshark