文件I/O基础
本章将介绍Linux应用编程中最基础的知识,即文件I/O(Input/Output)。文件I/O指的是对文件进行读写操作,在Linux系统中一切皆文件,这是Linux系统设计的核心理念,因此文件I/O操作既是基础又是最重要的部分。本章将讨论以下主题:
文件描述符的概念
打开文件(open())和关闭文件(close())
写文件(write())和读文件(read())
文件读写位置偏移量
1、概念
文件 I/O(input/output) 指的是对文
件的输入/输出操作,即对文件的读写操作
流程
-
打开文件
-
读写文件
-
关闭文件
文件描述符
-
概念
-
在 open函数执行成功的情况下,会返回一个非负整数,该返回值就是一个文件描述符(file descriptor)
-
文件句柄
-
一个非负整数
-
与对应文件相绑定
- 所有打开的文件都会通过文件描述符进行索引
-
-
-
分配
-
分配一个最小的没有被使用的整数作为文件描述符
-
文件描述符一般都是从 3 开始
- 0、1、2 这三个文件描述符已经默认被系统占用
了,分别分配给了系统标准输入(0)、标准输出(1)以及标准错误(2)
- 0、1、2 这三个文件描述符已经默认被系统占用
-
-
Linux 系统下,一切皆文件
2、打开文件:open()函数
原型
-
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h> -
int open(const char *pathname, int flags);
- 用于打开文件
-
int open(const char *pathname, int flags, mode_t mode);
- 用于创建文件
参数
-
pathname
- 标识需要打开或创建的文件,可以包含路径(绝对路径或相对路径)信息
-
flags
-
文件访问模式标志以及其它文件相关标志
-
既可以单独使用某一个标志,也可以通过位或运算(|)
-
不同内核版本所支持的 flags 标志是存在差别的
-
-
mode
-
指定新建文件的访问权限
-
只有当 flags 参数中包含 O_CREAT 或O_TMPFILE 标志时才有效(O_TMPFILE 标志用于创建一个临时文件)
-
通过 chmod 命令对文件权限进行修改
-
使用"ls -l"命令来查看到文件所对应的权限
-
u32 无符号整形数据
-
O—这 3 个 bit 位用于表示其他用户的权限
-
G—这 3 个 bit 位用于表示同组用户(group)的权限,即与文件所有者有相同组 ID 的所有用户
-
U—这 3 个 bit 位用于表示文件所属用户的权限,即文件或目录的所属者
-
S—这 3 个 bit 位用于表示文件的特殊权限
-
-
返回值
- 成功将返回文件描述符,文件描述符是一个非负整数;失败将返回-1
3、写文件:write()函数
原型
-
#include <unistd.h>
-
ssize_t write(int fd, const void *buf, size_t count);
参数
-
fd
- 文件描述符,指定目标文件
-
buf
- 指定写入数据对应的缓冲区,即存放要写入的数据
-
count
- 指定写入的字节数
返回值
-
如果成功将返回写入的字节数(0 表示未写入任何字节)
-
如果此数字小于 count 参数,这不是错误,譬如磁盘空间已满,可能会发生这种情况
-
如果写入出错,则返回-1
4、读文件:read()函数
原型
-
#include <unistd.h>
-
ssize_t read(int fd, void *buf, size_t count);
参数
-
fd
- 文件描述符,指定目标文件
-
buf
- 指定用于存储读取数据的缓冲区
-
count
- 指定需要读取的字节数
返回值
-
成功读取后返回实际读取的字节数。
-
实际读取的字节数可能小于 count 参数指定的字节数。可能情况包括:
-
当前文件位置偏移量已经到了文件末尾,此时 read 函数返回成功但实际读取字节数为 0。
-
当要求读取的字节数大于文件剩余的字节数时,read 函数只能返回文件剩余字节数,而不会读取更多。
-
举例:如果文件在末尾之前只有 30 个字节数据,而要求读取 100 个字节,则 read 函数成功调用时只能返回 30;而下一次再调用 read 读取时,则会返回 0(表示已到达文件末尾)。
-
-
如果写入出错,则返回-1
5、关闭文件:close()函数
原型
-
#include <unistd.h>
-
int close(int fd);
参数
-
fd
- 文件描述符,需要关闭的文件所对应的文件描述符
返回值
-
如果成功返回 0
-
如果失败则返回-1
6、调整读写位置偏移:lseek()函数
原型
-
#include <sys/types.h>
#include <unistd.h> -
off_t lseek(int fd, off_t offset, int whence);
参数
-
fd
- 文件描述符,目标文件
-
offset
- 偏移量,以字节为单位
-
whence
-
用于定义参数 offset 偏移量对应的参考值,该参数为下列其中一种(宏定义):
-
SEEK_SET
- 读写偏移量将指向 offset 字节位置处(从文件头部开始算)
-
SEEK_CUR
- 读写偏移量将指向当前位置偏移量 + offset 字节位置处,offset 可以为正、也可以为负
-
SEEK_END
- 读写偏移量将指向文件末尾 + offset 字节位置处,同样 offset 可以为正、也可以为负
-
-
返回值
-
成功将返回从文件头部开始算起的位置偏移量(字节为单位)
-
错误将返回-1