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

文件IO、目录IO

在 Linux 内核中,文件 I/O(输入/输出)操作涉及一组系统调用,这些调用是用户空间程序与内核空间文件系统之间的接口。常见的文件 I/O 操作包括 open()、read()、write()、lseek() 等,这些系统调用提供了访问文件、读取文件内容、写入数据和操作文件指针等功能。

1. open() 系统调用
open() 用于打开一个文件或者创建一个文件,并返回文件描述符(file descriptor)。它的原型如下:

int open(const char *pathname, int flags, mode_t mode);

pathname:文件路径。
flags:打开文件的方式,常见的标志有:
O_RDONLY:只读模式
O_WRONLY:只写模式
O_RDWR:读写模式
O_CREAT:文件不存在时创建
O_APPEND:以追加模式打开文件
O_TRUNC:文件存在时截断为0大小
mode:如果文件被创建(O_CREAT 标志),则指定文件的权限(如 S_IRUSR, S_IWUSR 等)。
open() 函数返回一个非负整数的文件描述符(文件句柄),如果出错,则返回 -1。

内核实现:
在内核中,open() 系统调用通过 do_sys_open() 函数来实现。内核会根据 flags 参数判断如何打开文件,并调用具体的文件系统接口来完成文件的打开操作。

2. read() 系统调用
read() 用于从文件中读取数据。它的原型如下:

ssize_t read(int fd, void *buf, size_t count);

fd:文件描述符,由 open() 返回。
buf:指向存储读取数据的缓冲区。
count:要读取的字节数。
read() 会返回实际读取的字节数,如果遇到文件末尾(EOF),返回 0;出错时返回 -1。

内核实现:
在内核中,read() 会调用对应文件系统的 read() 方法,通常是通过 vfs_read() 函数。这会先查找文件系统的相关操作,然后读取数据并将其拷贝到用户空间缓冲区。

3. write() 系统调用
write() 用于向文件写入数据。它的原型如下:

ssize_t write(int fd, const void *buf, size_t count);

fd:文件描述符,由 open() 返回。
buf:指向包含要写入数据的缓冲区。
count:要写入的字节数。
write() 返回实际写入的字节数。如果出现错误,返回 -1。

内核实现:
在内核中,write() 系统调用通过 vfs_write() 函数来实现。具体的文件系统会根据需要将数据写入磁盘,操作涉及到文件缓存管理和磁盘 I/O。

4. lseek() 系统调用
lseek() 用于改变文件的读取/写入位置。它的原型如下:

off_t lseek(int fd, off_t offset, int whence);

fd:文件描述符。
offset:偏移量。
whence:如何解释偏移量,常见的值有:
SEEK_SET:从文件的开头开始偏移。
SEEK_CUR:从当前位置偏移。
SEEK_END:从文件末尾偏移。
lseek() 返回新的文件位置(以字节为单位)。如果出错,返回 -1。

内核实现:
在内核中,lseek() 系统调用通过 vfs_llseek() 来实现,它会根据文件的类型和文件系统的不同来处理文件偏移操作。对于普通文件,它会更新文件的文件指针;对于某些特殊文件(如设备文件),lseek() 可能会有不同的实现。

5. 文件 I/O 的文件系统层
在内核中,文件系统通过一组虚拟文件系统(VFS)接口来管理文件。VFS 是一个抽象层,允许不同的文件系统(如 ext4、xfs、ntfs 等)通过统一的接口进行操作。VFS 提供了很多与文件操作相关的函数,如 vfs_read()、vfs_write()、vfs_open() 等。

内核中文件 I/O 相关的主要结构和函数:
file_operations 结构体:包含一组指向操作函数的指针,如 read(), write(), open(), release() 等。这些函数处理文件的具体操作。
inode 结构体:表示文件的元数据,如文件类型、权限、大小等。
file 结构体:表示文件描述符,包含文件指针等信息。
dentry 结构体:表示目录项,用于目录的遍历。
文件 I/O 流程概述:
打开文件:

用户调用 open() 系统调用。
内核通过 vfs_open() 查找文件并返回文件描述符。
读取文件:

用户调用 read() 系统调用。
内核通过 vfs_read() 获取数据并拷贝到用户空间。
写入文件:

用户调用 write() 系统调用。
内核通过 vfs_write() 将数据写入文件系统。
调整文件指针:

用户调用 lseek() 系统调用。
内核通过 vfs_llseek() 调整文件的读写位置。
总结
open():打开文件,返回文件描述符。
read():从文件读取数据。
write():向文件写入数据。
lseek():调整文件的读写位置。

相关文章:

  • C/C++字符串格式化全解析:从printf到std::format的安全演进与实战指南
  • uv 简易安装与更换国内镜像源
  • Function.prototype.__proto__==Object.prototype
  • 如何使用OPENAI的Whisper功能进行音频字母提取功能
  • 大数据技术Kafka详解 ⑥ | Kafka大厂面试题
  • FreeRTOS第11篇:FreeRTOS——移植与裁剪
  • Redis原理简述及发布订阅消息队列
  • 无人机+低轨卫星:无限距离集群网络技术详解
  • Vue 项目登录的基本流程
  • Python学习心得异常处理
  • MySQL 深分页速度慢的原因及优化方案
  • MWORKS Syslab(个人版)安装教程
  • CViewState::InitializeColumns函数分析之_hdsaColumnStates的结构
  • PySide6 GUI 学习笔记——常用类及控件使用方法(常用类尺寸QSize)
  • 【前端】Vue组件库之Element: 一个现代化的 UI 组件库
  • 在Kubernetes上部署DeepSeek-R1进行高效AI推理
  • SpringBoot 核心总结图
  • Redis 回收进程工作流程详解
  • 【Python 学习 / 5】函数详解(定义、参数、作用域、lambda、内置函数)
  • Redis 简介
  • “上报集团文化助力区域高质量发展赋能平台”揭牌
  • 【社论】优化限购限行,激发汽车消费潜能
  • 脱发后怎么把头发养回来?脱发自救指南来了
  • 广东一公司违规开展学科培训被罚没470万,已注销营业执照
  • 解放日报头版头条:“五个中心”蹄疾步稳谱新篇
  • 专访|伊朗学者:美伊核谈不只是改革派立场,但伊朗不信任美国