Linux学习-应用软件编程(文件IO)
Linux内核专门为应用层提供的文件操作方式。
1.打开文件 open
2.读写文件 read/write
3.关闭文件 close
open
int open(const char *pathname, int flags);
int open(const char *pathname, int flags, mode_t mode);
头文件
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
功能
打开文件并获取文件描述符,用于后续文件操作(读写等 )。
参数
1. pathname
要打开的文件的文件名(包含路径,无路径则为当前工作目录下文件 )。
2. flags(打开方式,可组合,用 | 连接 )
- 只读: O_RDONLY
- 只写: O_WRONLY
- 可读可写: O_RDWR
- 创建文件: O_CREAT (文件不存在时创建,需配合 mode 设权限 )
- 清空文件: O_TRUNC (文件存在则长度截为 0 )
- 追加写: O_APPEND (写入数据到文件末尾 )
与标准 IO 打开模式对应关系(便于理解):
标准 IO 模式 对应 flags 组合
"r" O_RDONLY
"r+" O_RDWR
"w" `O_WRONLY | O_CREAT | O_TRUNC
"w+" `O_RDWR | O_CREAT | O_TRUNC
"a" `O_WRONLY | O_APPEND | O_CREAT
"a+" `O_RDWR | O_APPEND | O_CREAT
3. mode(文件权限, flags 含 O_CREAT 时必传 )
- 表示文件读写执行权限,如 0664 (对应 rw-rw-r-- )、 0777 ( rwxrwxrwx ) 。
- 实际生效权限会受 umask 掩码影响,计算方式: mode & ~umask 。例: mode 为 0777 , umask 为 002 ,则实际权限 0775 ( rwxrwxr-x ) 。
返回值
成功:文件描述符
失败:-1
int main(int argc,const char*argv[])
{int fd = open("./1.txt",O_WRONLY | O_CREAT | O_TRUNC,0664);if(-1 == fd){printf("open error\n");return -1;}printf("fd = %d\n",fd);close(fd);
}
操作系统启动后,默认占用 0、1、2 三个文件描述符:
- 0 :标准输入( stdin ,对应键盘等输入设备 )
- 1 :标准输出( stdout ,对应终端屏幕输出 )
- 2 :标准错误( stderr ,终端输出错误信息 )
close
#include <unistd.h>
int close(int fd);
功能
关闭文件描述符对应文件,释放系统资源
参数
fd 为要关闭的文件描述符
write
ssize_t write(int fd, const void *buf, size_t count);
功能
向 fd 关联文件写入数据
参数
- fd :目标文件描述符
- buf :待写入数据的内存首地址(常为数组、缓冲区指针 )
- count :期望写入的字节数
返回值
成功:返回实际写入字节数(可能因磁盘满等 < count );
失败:返回 -1
read
ssize_t read(int fd, void *buf, size_t count);
功能
从 fd 关联文件读取数据到内存
参数
- fd :源文件描述符
- buf :存储读取数据的内存首地址(需提前分配足够空间 )
- count :期望读取的字节数
返回值
成功:返回实际读到字节数(文件末尾可能 < count );
失败:返回 -1 ,
读到文件末尾:返回 0
文件定位函数
lseek
off_t lseek(int fd, off_t offset, int whence);
功能
用于定位文件读写位置,控制 read / write 操作在文件的具体字节位置生效 。
参数
fd :目标文件的文件描述符(通过 open 等函数获取 ) 操作已打开文件 test.txt 的 fd
offset :偏移量(字节为单位,可正可负,正表示向后偏移,负表示向前 ) 想跳过 100 字节: offset=100 ;回退 50 字节: offset=-50
whence :相对位置基准,有 3 种宏定义:
- SEEK_SET :文件开头
- SEEK_CUR :当前读写位置
- SEEK_END :文件末尾 从开头偏移:
返回值
- 成功:返回当前读写位置相对于文件开头的偏移量( off_t 类型,通常是长整型 )
- 失败:返回 -1 ,可通过 errno 查看具体错误(如 EBADF 表示 fd 无效 )
求文件大小:
off_t len = lseek(fd, 0, SEEK_END);
// 先定位到文件末尾,返回值就是文件总字节数(因从开头到末尾的偏移量 = 文件大小 )
lseek(fd, 0, SEEK_SET);
// 操作完文件大小获取,重置读写位置到开头,方便后续正常读写
标准 IO(C 库函数)
特性 说明
归属与移植性 属于 C 库函数,跨平台(Windows、Linux 等)移植性强
实现本质 对系统调用的封装,内部增加缓冲区(批量读写,减少系统调用次数,提升普通文件读写效率)
主要应用场景 专注普通文件操作(文本、二进制文件读写,如日志、配置文件处理 )
典型函数 fopen / fclose (打开/关闭)、 fread / fwrite (读写)、 fseek (定位)等
文件 IO(系统调用)
特性 说明
归属与移植性 属于 Linux 系统调用,依赖内核实现,跨不同操作系统(如 Windows)移植性弱
实现本质 无用户态缓冲区,直接与操作系统内核交互,每次操作近乎直接触发硬件 IO(灵活但普通文件读写效率可能低于标准 IO )
主要应用场景 侧重硬件设备操作(串口、磁盘分区等),也支持普通文件;对实时性、硬件直接控制需求场景更适配
典型函数 open / close (打开/关闭)、 read / write (读写)、 lseek (定位)等
缓冲区
行缓冲(1024 字节,交互场景)
刷新触发条件
行缓冲 人机交互界面、终端(如 stdout )
1. 程序正常结束(自动刷)
2. 遇到换行符 \n
3. 调用 fflush() 强制刷
4. 缓冲区写满(1024 字节) 命令行工具实时输出、终端日志打印
全缓冲(4096 字节,文件场景)
全缓冲 文件操作(如 fopen 打开的文件)
1. 程序正常结束(自动刷)
2. 调用 fflush() 强制刷
3. 文件关闭( fclose 时自动刷)
4. 缓冲区写满(4096 字节) 普通文件读写(日志、文档存储 )
无缓冲(0 字节,错误输出)
无缓冲 错误输出设备(如 stderr ) 数据产生后立即输出,无需缓冲触发条件 错误信息实时显示(程序崩溃日志、调试信息 )