文件I/O的系统调用
有关文件I/O的Linux系统调用主要有4个函数(当然不会只有这4个的):
- open
- read
- write
- close
文件描述符
文件描述符是一个非负整数。当一个进程打开( open )一个文件时,系统就会返回给进程一个文件描述符,而该进程就可以通过这个文件描述符来对打开的文件进行读/写( read / write )。
很明显一个文件描述对应着一个 打开了的 文件,不同文件的文件描述符肯定是不同的。当进程完成了对文件的读写操作后,还需要关闭( close )该文件。文件一旦被关闭,其所对应的文件描述符也会被释放,被释放的文件描述符可以被再次使用与其它文件相关联。
在默认情况下,一个进程一旦被创建就会打开三个文件:
- 标准输入,与其相关联的文件描述符为0
- 标准输出,与其相关联的文件描述符为1
- 标准错误,与其相关联的文件描述符为2
(注意:Linux中一切都是文件)
为了提高可读性,在 <unistd.h> 中定义了三个常量STDIN_FILENO、STDOUT_FILENO、STDERR_FILENO来分别表示0、1、2三个文件描述符。
需要注意的是一个进程能打开的文件数量是有限制的,被定义为OPEN_MAX,因此文件描述符也就有了一个范围: 0~OPEN_MAX-1 。
open系统调用
一个文件需要被打开才能对其进一步操作,open就是用于打开文件的系统调用。
>> 函数原型如下:
#include <fcntl.h>
int open(const char *path, int oflags, ...\*mode_t mode*\);
>> 函数的返回值: 调用成功时,函数就会返回一个文件描述符方便程序对文件进行操作。
>> 函数的参数:
- const char *path是要打开的文件的路径名,以字符串的形式传入。
- int oflags是一个标志参数,用于控制函数的具体行为。
- mode_t mode是一个可选参数(即可以不使用该参数),与文件权限有关(后面会提到)。
>> 有关oflags参数:
oflags参数是通过多个可选的值以"或"逻辑组合而成的。
oflags可选的模式 | 说明 |
---|---|
O_RDONLY | 以只读方式打开 |
O_WRONLY | 以只写方式打开 |
O_RDWR | 以读写方式打开 |
O_EXEC | 以只执行方式打开 |
O_SEARCH | 以只搜索方式打开 |
注意上面的五个选项必须有且仅有一个作为参数oflags的模式组合中的一个值 | |
下面列出的模式可有可无还可以有多个 | |
O_APPEND | 每次进行写操作时都追加在文件的尾端 |
O_TRUNC | 把文件长度设置为0(已有的内容被丢弃),即文件长度截断为0 |
O_CREAT | 若文件不存在则创建文件,该模式必须使用open函数的第三个参数mode来设置文件的权限 |
O_EXCL | 用于测试文件是否存在。与O_CREAT一起使用,若文件存在则出错,不存在则创建文件。 |
* 注:以上仅列出部分模式
>> 有关mode参数:
在oflags中选用了O_CREAT标志时就需要传入mode参数。mode参数同样是由多个标志选项通过"或"逻辑操作得到的一个组合值。
mode标志选项定义于头文件 <sys/stat.h> 中:
mode标志选项 | 说明 |
---|---|
S_IRUSR | 读权限,文件属主 |
S_IWUSR | 写权限,文件属主 |
S_IXUSR | 执行权限,文件属主 |
S_IRGRP | 读权限,文件所属组 |
S_IWGRP | 写权限,文件所属组 |
S_IXGRP | 执行权限,文件所属组 |
S_IROTH | 读权限,其他用户 |
S_IWOTH | 写权限,其他用户 |
S_IXOTH | 执行权限,其他用户 |
read系统调用
read系统调用用于读取一个已经打开了的文件的数据。
>> read函数的原型如下:
#include <unistd.h>
size_t read(int fildes, void *buf, size_t nbytes);
>> 函数的作用: 从一个文件中读取指定字节的数据,并将读取的数据放到数据区buf中。
>> 函数的返回值: 当函数调用成功时,将返回实际读取的字节数;若调用失败则返回-1。
>> 函数的参数:
- int fildes是将要读取的文件所对应的文件描述符
- void *buf指向数据区
- size_t nbytes是希望读取的字节数
write系统调用
系统调用write用于对文件的写操作,其作用是将缓冲区buf的前指定数量的字节写入文件中。
>> write函数的原型如下:
#include <unistd.h>
size_t write(int fildes, const void *buf, size_t nbytes);
>> 函数的返回值: 当函数调用成功时返回实际写入的数据;若调用失败则返回-1
>> 函数的参数:
- int fildes是将要写入数据的文件所对应的文件描述符
- const void *buf是数据缓冲区
- size_t nbytes是期望写入的数据字节数
close系统调用
当对某一文件的操作完毕时,就需要关闭该文件,使得该文件所对应的文件描述符得以释放,方便该描述符下一次的使用。
>> close函数的原型如下:
#include <unistd.h>
int close(int fildes);
close函数非常简单,只需要将期望关闭的文件所对应的描述符作为参数传入即可。若关闭成功则返回0,出错则返回-1。