第一章 Linux文件I/O
1.1 引言
本章内容描述Linux系统的文件IO,Linux可用的文件IO函数有——打开文件、关闭文件、写文件等。linux系统中的大多数文件I/O子需要用到5个函数:open、read、write、lseek以及close。本章描述说明的函数经常被称为不带缓存的I/O(unbuffered I/O)。属术语不带缓存指的是每个read和write都调用内核的一个系统调用,这些不带缓冲的I/O函数不是ISO C的组成部分,但是它们是POSIX.1和Single UNIX Specigication的组成部分。
1.2 文件描述符
对于内核而言所有打卡的文件都是通过文件描述符引用。文件描述符是一个非负整数。当打开一个现有文件或创建一个新文件时,内核向进程返回一个文件描述符fd。当要读写一个文件时将文件描述符传入read或者write。
linux系统shell把文件描述符0与进程标准输入关联,文件描述符1与标准输出关联,文件描述符2与标准错误关联。
在符合POSIX.1的应用程序中幻数0、1、2的使用应该替换成符号常量STDIN_FILENO、STDOUT_FILENO和STDERR_FILENO ,这些常量被定义在头文件<unistd.h>内。
1.3 文件IO的API
- 打开和创建文件
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
/*******************************************************************************
* open()函数用于打开文件
* @pathname :要打开的文件名,包文件文件路径
* @flags :打开文件的方式,支持以下几种:
* O_RDONLY:以只读方式打开文件
* O_WDONLY:以只写方式打开文件
* O_RDWD :以读写方式打开文件
* O_EXRC :只执行打卡
* O_SEARCH:只执行搜索
* O_TTY_INIT:打卡一个终端设备。设置非标准的terios参数值。
* @mode :
* @return :成功返回最小的文件描述符,失败返回-1
********************************************************************************/
int open(const char *pathname, int flags);
int open(const char *pathname, int flags, mode_t mode);
/*******************************************************************************
* create()函数用于创建文件,等效于:open(pathname, O_WRONLY|O_CREATE ,mode);
* create()函数只能以只写方式创建文件。
* @pathname :要打开的文件名,包文件文件路径
* @flags :打开文件的方式,支持以下几种:
* O_RDONLY:以只读方式打开文件
* O_WDONLY:以只写方式打开文件
* O_RDWD :以读写方式打开文件
* O_EXRC :只执行打卡
* O_SEARCH:只执行搜索
* O_TTY_INIT:打卡一个终端设备。设置非标准的terios参数值。
* @mode :
* @return :成功返回只写文件描述符,失败返回-1
********************************************************************************/
int creat(const char *pathname, mode_t mode);
/*******************************************************************************
* openat()函数用于打开文件,这个函数打开文件有三种可能:
* 1. pathname 指定绝对路径,在这种情况下dirfd参数没忽略openat相当于open;
* 2. pathname 指定相对路径,fd参数指出相对路径在文件系统中的开始地址。参数
* 是通过打开相对路径名的目录来获取。
* 3. pathname 指定相对路径,fd参数具有特殊值AT_FDCWD,在这种情况下路径名在
* 当前工作目录在获取,openat函数在操作上和open函数类似。
* @pathname :要打开的文件名,包文件文件路径
* @flags :打开文件的方式,支持以下几种:
* O_RDONLY:以只读方式打开文件
* O_WDONLY:以只写方式打开文件
* O_RDWD :以读写方式打开文件
* O_EXRC :只执行打卡
* O_SEARCH:只执行搜索
* O_TTY_INIT:打卡一个终端设备。设置非标准的terios参数值。
* @mode :
* @return :成功,返回大于0的文件描述符,失败雄小于0
********************************************************************************/
int openat(int dirfd, const char *pathname, int flags);
int openat(int dirfd, const char *pathname, int flags, mode_t mode);
- 关闭文件
#include <unistd.h>
/*******************************************************************************
* close()函数用于关闭文件
* @fd:要关闭的文件的文件描述符
* @return:成功返回0,失败返回-1,并设置errno
********************************************************************************/
int close(int fd);
- 文件偏移
#include <sys/types.h>
#include <unistd.h>
/*******************************************************************************
* lseek()函数设置文件偏移量,即文件读写开始的位置
* @fd : 文件描述符
* @offset : 文件偏移offset个位置
* @whence : 控制文件偏移位置的起点,有以下控制方式:
* SEEK_SET:将该文件的偏移量设置为距文件开始处offset个字节
* SEEK_CUR:将该文件的偏移量设置为文件当前位置加offset个字节,offset可正可负
* SEEK_END:将该文件的偏移量设置为文件末尾加offset个字节,offset可正可负
* return : 成功返回新的文件偏移量,失败返回-1
********************************************************************************/
off_t lseek(int fd, off_t offset, int whence);
- 读取文件
#include <unistd.h>
/*******************************************************************************
* read()函数用于读取文件,会更改文件偏移指针
* @fd : 文件描述符
* @buf : 存放读取的文件数据
* @count : 要读的文件字节数
* return :读到的字节数,读到文件末尾返回0,失败返回-1
* -------------------------------------------------------------------------------
* 1.读取终端设备时,通常一次最多读一行。
* 2.读取网络数据时,网络的缓存机制可能造成返回值小于所要读取的字节数
* 3.读取管道或者FIFO时,若管道包含的字节少于所需的数量,那么read返回实际的字节数
********************************************************************************/
ssize_t read(int fd, void *buf, size_t count);
- 写入文件
#include <unistd.h>
/*******************************************************************************
* write()函数用于读取文件,会更改文件偏移指针
* @fd : 文件描述符
* @buf : 要写入文件的数据
* @count : 要写入的字节数
* return :成功返回写入的字节数,失败返回-1
********************************************************************************/
ssize_t write(int fd, void *buf, size_t count);
文件共享
- 函数dup和dup2
#include <unistd.h>
/*******************************************************************************
* dup()和dup2()函数用于读取文件,会更改文件偏移指针
* @oldfd : 文件描述符
* @newfd : 新的文件描述符
* @return : 成功返回新的文件描述符,失败返回-1
********************************************************************************/
int dup(int oldfd);
int dup2(int oldfd, int newfd);
#define _GNU_SOURCE /* See feature_test_macros(7) */
#include <fcntl.h> /* Obtain O_* constant definitions */
#include <unistd.h>
int dup3(int oldfd, int newfd, int flags);
参考文献
[1] UNIX环境高级编程 中文第三版