学嵌入式和Linux应用编程|学习日记Day24:Linux系统IO文件编程学习笔记
|
学习主题:Linux 文件 IO 系统调用,open/read/write/close/lseek,文件 IO 与标准 IO 对比、缓冲区、格式化输出系列函数 |
前言
今天告别 C 库的标准 IO,深入学习 Linux 内核提供的文件 IO 系统调用。这是嵌入式 Linux 开发非常核心的知识点,硬件设备操作、底层文件读写都会用到这套 API。系统调用直接和内核打交道,没有用户层缓冲区,和之前学的FILE*标准库接口有很大区别。
一、文件 IO 基础概念
文件 IO 是 Linux 内核提供的文件操作接口,属于系统调用。
核心学习接口分为四组:
- 打开文件:open()
- 读写文件:read()、write()
- 关闭文件:close()
- 文件定位:lseek()
1.1 open 函数
头文件
|
c |
函数原型
|
c |
功能:打开一个文件,成功后获取一个文件描述符。
|
参数 |
说明 |
|
pathname |
要打开的文件路径 + 文件名 |
|
flags |
打开方式,多个可以位或组合 |
|
mode |
新建文件时,设置文件操作权限(mode & ~umask) |
flags 常用宏:
- O_RDONLY:只读
- O_WRONLY:只写
- O_RDWR:读写
- O_CREAT:文件不存在则创建
- O_TRUNC:清空原有文件内容
- O_APPEND:追加写入
|
注意:使用O_CREAT的时候,必须带上 mode 参数;普通文件常用权限0664,权限满为0777。 |
返回值
- 成功:返回文件描述符(非负整数)
- 失败:返回-1
1.2 文件描述符
打开文件时,操作系统会分配文件描述符用来标识该文件。
- 文件描述符:小的、非负整型数字
- 系统可分配总数量:0‑1023,一共 1024 个
- 分配原则:选取最小未被使用的数字
系统默认预先打开 3 个文件描述符:
|
fd 数值 |
宏名 |
含义 |
|
0 |
STDIN_FILENO |
标准输入 stdin |
|
1 |
STDOUT_FILENO |
标准输出 stdout |
|
2 |
STDERR_FILENO |
标准错误 stderr |
1.3 close 关闭文件
头文件
|
c |
原型
|
c |
功能:关闭已经打开的文件。
参数:fd,要关闭的文件描述符。
返回:成功返回 0;失败返回‑1。
|
⚠️重要提醒:打开的文件一定要 close,不关闭会造成文件描述符泄露,耗尽可用 fd,后续无法打开任何文件。 |
1.4 write 写文件
|
c |
功能:向打开的文件写入数据。
- fd:目标文件描述符
- buf:待写入数据的首地址
- count:想要写入的字节数量
返回值:成功返回实际写入字节数;失败返回‑1。
1.5 read 读文件
|
c |
功能:从文件读取数据。
- fd:文件描述符
- buf:存放读取内容的内存首地址
- count:期望读取的字节数
返回值:成功返回读到的字节数;失败返回‑1。1.6 lseek 文件定位函数
头文件
|
c |
原型
|
c |
功能:重新修改文件读写指针的位置。
|
参数 |
解释 |
|
fd |
文件描述符 |
|
offset |
偏移量 |
|
whence |
偏移的起始基准位置 |
whence 三个可选宏:
- SEEK_SET:文件开头
- SEEK_CUR:当前读写位置
- SEEK_END:文件末尾
返回值:成功返回当前位置距离文件开头的偏移字节;失败返回‑1。
二、文件 IO vs 标准 IO 对比
对比表格
|
对比项 |
标准 IO |
文件 IO(系统调用) |
|
操作对象 |
FILE* 文件流指针 |
fd 文件描述符 |
|
来源 |
C 库函数,可移植性强 |
Linux 系统调用,可移植弱 |
|
缓冲区 |
具备用户缓冲区,减少用户态内核态切换,提升效率 |
无用户缓冲区,实时性能好 |
|
主要场景 |
普通文件读写 |
普通文件、硬件相关设备文件 |
三种缓冲区详解
- 行缓冲:默认大小:2048 字节(1K),多用于人机交互终端。刷新触发条件:遇到\n换行;程序结束;调用fflush();缓冲区写满。
- 全缓冲:默认大小:4096 字节(4K),多用于普通文件交互。刷新触发条件:程序结束;文件关闭;缓冲区写满;手动fflush()。
- 无缓冲:大小 0K,典型代表:stderr标准错误,错误信息直接输出,不缓存。
三、格式化输出系列函数
|
c |
核心作用:
- 将格式化后的字符串写入目标位置(终端、文件、内存数组)
- 可以把整型、浮点型数据,转换为字符串,完成字符串拼接格式化。
四、今日学习小结
- open/read/write/close/lseek 是 Linux 系统调用,直接陷入内核,没有用户缓冲区,嵌入式操作硬件设备经常使用。
- 文件描述符 0、1、2 程序启动默认打开,对应输入输出错误;用完 fd 必须 close,防止泄露。
- 标准 IO 带缓冲区,文件 IO 不带缓冲区;行缓冲、全缓冲、无缓冲三种刷新条件要分清。
- printf / fprintf / dprintf / sprintf 四个格式化函数,目标对象不一样:终端、FILE 流、fd、内存数组。
|
小练习提示:可以写一个简单文件复制 demo,使用 open read write close 完成文件拷贝,巩固今天系统调用 API。 |
openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构
更多推荐


所有评论(0)