linux 高级I/O函数
1、open
用于打开或创建文件、设备文件等。
1 |
|
pathname:这是一个字符串指针,指向要打开或创建的文件的路径名。可以是绝对路径(如 /home/user/test.txt),也可以是相对路径(如 test.txt)。
flags:这是一个整数,用于指定打开文件的方式和一些额外的选项。常用的标志位如下:
O_RDONLY:以只读模式打开文件。
O_WRONLY:以只写模式打开文件。
O_RDWR:以读写模式打开文件。
O_CREAT:如果文件不存在,则创建该文件。使用此标志时,需要同时提供第三个参数 mode 来指定文件的权限。
O_EXCL:与 O_CREAT 一起使用时,如果文件已经存在,则 open 函数会失败并返回 -1,可用于确保创建一个新文件。
O_TRUNC:如果文件存在且以写模式打开,则将文件截断为长度为 0。
O_APPEND:以追加模式打开文件,每次写操作都会将数据追加到文件末尾。
mode:当使用 O_CREAT 标志时,需要提供此参数来指定新创建文件的权限。mode 是一个八进制数,通常使用 umask 来屏蔽一些权限位。例如,0644 表示文件所有者具有读写权限,而组用户和其他用户具有只读权限。
2、read/write
用于执行文件 I/O(输入 / 输出)操作的基础函数,它们可以对文件、设备等进行数据的读取和写入。
1 |
|
fd:这是一个文件描述符,代表要读取数据的文件、设备等。文件描述符通常是通过 open、socket 等函数返回得到的。
buf:这是一个指向缓冲区的指针,用于存储从文件中读取的数据。读取的数据会被存储到这个缓冲区中。
count:这是一个 size_t 类型的整数,表示要读取的最大字节数。
返回值
正数:表示实际成功读取的字节数。
0:表示已经到达文件末尾,没有更多数据可供读取。
-1:表示读取操作失败,此时 errno 会被设置为具体的错误码,可以通过 perror 或 strerror 函数来获取错误信息。
3、lseek
用于移动文件读写指针的位置。
1 |
|
fd:文件描述符,代表要操作的文件。这个文件描述符通常是通过 open 函数打开文件后返回得到的。
offset:偏移量,它是一个 off_t 类型的整数,用于指定从 whence 参数所指定的位置开始移动的字节数。可以是正数(表示向文件末尾方向移动)、负数(表示向文件开头方向移动)或 0。
whence:指定偏移量的起始位置,它有以下三种取值:
SEEK_SET:从文件的开头开始计算偏移量,即 offset 是相对于文件开头的字节数。
SEEK_CUR:从文件的当前读写位置开始计算偏移量,offset 是相对于当前位置的字节数。
SEEK_END:从文件的末尾开始计算偏移量,offset 是相对于文件末尾的字节数,通常 offset 取负数表示向文件开头方向移动。
返回值
成功:返回从文件开头到新的文件读写指针位置的字节数,类型为 off_t。
失败:返回 -1,并设置 errno 变量来指示具体的错误原因。常见的错误包括无效的文件描述符、不支持随机访问的设备等。
4、stat/lstat
用于获取文件或文件系统对象的状态信息,例如文件的权限、大小、创建时间、修改时间等。不过,它们在处理符号链接时有一些差异。
stat
1 |
|
pathname:一个指向字符串的指针,代表要获取状态信息的文件或目录的路径名。可以是绝对路径(如 /home/user/test.txt),也可以是相对路径(如 test.txt)。
buf:一个指向 struct stat 结构体的指针,用于存储获取到的文件状态信息。
struct stat 结构体定义如下:
1 | struct stat { |
返回值
成功:返回 0。
失败:返回 -1,并设置 errno 变量来指示具体的错误原因,例如文件不存在、权限不足等。
lstat
1 |
|
与 stat 函数的参数相同,pathname 是要获取状态信息的文件或目录的路径名,buf 是用于存储文件状态信息的 struct stat 结构体指针。
区别
当 pathname 是一个符号链接时,lstat 函数不会跟随符号链接,而是返回符号链接本身的状态信息。这意味着 lstat 函数可以用来判断一个文件是否为符号链接,因为符号链接的 st_mode 字段会有特定的标志位。
如果你需要获取符号链接所指向的目标文件的状态信息,应该使用 stat 函数。
如果你需要获取符号链接本身的状态信息,或者判断一个文件是否为符号链接,应该使用 lstat 函数。
5、pipe
主要用于在进程间进行通信,创建的管道是一种半双工的通信机制,即数据只能在一个方向上流动
1 |
|
pipefd是一个包含两个整数的数组,用于存储管道的文件描述符。具体如下:
pipefd[0]:表示管道的读端文件描述符,进程可以通过这个文件描述符从管道中读取数据。
pipefd[1]:表示管道的写端文件描述符,进程可以通过这个文件描述符向管道中写入数据。
返回值
成功:返回 0,并且 pipefd 数组会被正确填充为管道的读端和写端文件描述符。
失败:返回 -1,并设置 errno 变量来指示具体的错误原因,常见的错误包括 EMFILE(当前进程已经打开了太多的文件描述符)、ENFILE(系统范围内的文件描述符已经用尽)等。
6、dup/dup2
dup
用于复制现有的文件描述符。
1 |
|
oldfd:需要被复制的现有文件描述符。
返回值
成功:返回一个新的文件描述符,这个新的文件描述符与 oldfd 指向同一个文件表项。
失败:返回 -1,并设置 errno 变量来指示具体的错误原因,例如 EBADF 表示 oldfd 不是一个有效的文件描述符。
dup2
dup2 函数同样用于复制文件描述符,但它允许用户指定新的文件描述符的值。
1 |
|
oldfd:需要被复制的现有文件描述符。
newfd:指定的新文件描述符的值。
返回值
成功:返回新的文件描述符(即 newfd)。
失败:返回 -1,并设置 errno 变量来指示具体的错误原因,例如 EBADF 表示 oldfd 或 newfd 不是有效的文件描述符。
7、fcntl
用于对已打开的文件描述符进行各种控制操作,比如改变文件的访问模式、获取或设置文件状态标志等。
1 |
|
fd:需要进行操作的文件描述符,通常是通过 open、pipe、socket 等函数返回得到的。
cmd:指定要执行的操作命令,不同的命令会有不同的功能,并且可能需要额外的参数。常见的命令有以下几类:
复制文件描述符:F_DUPFD、F_DUPFD_CLOEXEC。
获取 / 设置文件状态标志:F_GETFL、F_SETFL。
获取 / 设置文件锁:F_GETLK、F_SETLK、F_SETLKW。
获取 / 设置文件描述符标志:F_GETFD、F_SETFD。
…:这是一个可变参数,根据 cmd 的不同,可能需要提供额外的参数。例如,当 cmd 为 F_DUPFD 时,需要提供一个整数作为新文件描述符的最小值;当 cmd 为 F_SETFL 时,需要提供一个整数表示要设置的文件状态标志。
返回值
成功:返回值取决于具体的 cmd。例如,当 cmd 为 F_DUPFD 时,返回一个新的文件描述符;当 cmd 为 F_GETFL 时,返回文件的状态标志。
失败:返回 -1,并设置 errno 变量来指示具体的错误原因,常见的错误包括 EBADF(无效的文件描述符)、EINVAL(无效的 cmd 命令)等。