首先看一下Linux操作系统的分层结构:

可以看到IO分为两种,一种是标准I/O,属于C库函数,在应用层;一种是文件I/O,属于系统调用,在内核层,今天讲的是文件I/O。

概念

文件IO是在POSIX(可移植操作系统接口)中定义的一组输入输出函数,涉及操作系统和应用程序之间的交互用于读取和写入存储在永久性存储介质(如硬盘,SSD,USB闪存盘等)上的数据。

特点

1.没有缓冲机制,直接引用系统调用

2.围绕文件描述符进行操作,相当于标准IO中的流(FILE*),文件描述符是正整数

3.默认打开三个描述符:标准输入(0),标准输出(1),标准错误(2)

4.除了目录文件,其他类型文件都可以操作

5.可移植性相对较弱

与标准IO对比:

文件描述符

定义

        文件描述符是操作系统内核为每个打开的文件/设备分配的唯一整数标识符,用于标识和跟踪进程与文件的交互,在Linux/Unix中,它是底层文件IO操作的核心参数。

特点

1.唯一性:同一个进程内,每个文件描述符对应唯一的打开文件

2.非负整数:通常是小整数(如0、1、2),但可动态分配(如 open()返回的新描述符)

3.跨函数传递:可在不同系统调用间传递,代表对同一文件的持续操作

文件IO函数

文件IO函数是需要一些头文件的,可以在终端中用man来查看

#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>

1.open()打开文件

函数原型:

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

参数详解:

pathname:文件路径

flags:打开方式(可用|组合出现)

  • O_RDONLY 只读
  • O_WRONLY 只写
  • O_RDWR 读写
  • O_CREAT 文件不存在则创建
  • O_TRUNC 打开时清空文件
  • O_APPEND 追加写(从文件末尾写)
  • O_EXCL 配合 O_CREAT,文件已存在则报错

mode:仅在创建文件时需要,表示权限值,通常是0666

返回值:

成功:返回文件描述符fd(非负整数)

失败:返回-1

2.close()关闭函数

函数原型:

int close(int fd);

返回值:

成功:0

失败:-1

3.read()读函数

函数原型:

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

作用:从文件描述符fd读函数到缓冲区buf

参数:

fd:文件描述符

buf:存放数据的缓冲区

count:想要读的字节数

返回值:

>0:实际读到的字节数

=0:读到文件末尾(EOF)

-1:读取失败

4.write()写函数

函数原型:

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

作用:把缓冲区buf里面的数据写入文件fd

参数:

fd:文件描述符

buf:要写入的数据

count:要写入的字节数

返回值

>0:实际写入的字节数

-1:写入失败

5.lseek()移动文件读写的偏移量

函数原型:

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

作用:定位文件读写位置

参数:

offset:偏移量(正数向前,负数向后)

whence:基准位置

  • SEEK_SET:从文件开头偏移
  • SEEK_CUR:从当前位置偏移
  • SEEK_END:从文件末尾偏移

返回值:

成功:返回新的偏移量

失败:返回-1

常用技巧:用来获取文件大小,如:

int len = lseek(fd, 0, SEEK_END);

文件IO与标准IO的函数对比

功能 系统调用 IO 标准 C 库 IO
打开文件 open fopen
关闭文件 close fclose
读数据 read fread / fgets
写数据 write fwrite / fputs
定位偏移 lseek fseek / ftell / rewind
操作句柄 int fd FILE*
缓冲区
移植性 Linux 专用 跨平台

核心总结

  • 系统 IO 是底层函数,用 fd,无缓冲,直接访问内核。
  • 标准 IO 是上层库函数,用 FILE*,带缓冲,效率更高。
  • 所有打开必须关闭,防止资源泄漏。
  • read/write 返回值必须判断,是编程安全关键。
  • lseek/fseek 用来跳转文件读写位置。
Logo

openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构

更多推荐