【APUE学习笔记】第三章 文件I/O

  大多数UNIX文件I/O只需用到5个函数:open()、read()、write()、lseek()以及close()。

1.原子操作

  现代操作系统中,一般都提供了原子操作来实现一些同步操作,所谓原子操作,也就是一个独立而不可分割的操作。在单核环境中,一般的意义下原子操作中线程不会被切换,线程切换要么在原子操作之前,要么在原子操作完成之后。更广泛的意义下原子操作是指一系列必须整体完成的操作步骤,如果任何一步操作没有完成,那么所有完成的步骤都必须回滚,这样就可以保证要么所有操作步骤都未完成,要么所有操作步骤都被完成。

2.文件描述符

  对于内核而言,所有打开文件都由文件描述符引用。文件描述符是一个非负整数。当打开一个现存文件或创建一个新文件时,内核向进程返回一个文件描述符。当读、写一个文件时,用open()或creat()返回的文件描述符标识该文件,将其作为参数传送给read()或write()。
  标准输入、标准输出和标准出错:STDIN_FILENO、STDOUT_FILENO和STDERR_FILENO

3.文件I/O函数

3.1.open()

  功能:打开或创建一个文件

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int open(const char *pathname, int oflag,.../*, mode_t mode*/) ;
返回:若成功为文件描述符,若出错为-1

注:仅当创建新文件时才使用第三个参数

参数:pathname
要打开或创建的文件名,注意文件名长度有限制。
参数:oflag
O_RDONLY 只读打开
O_WRONLY 只写打开
O_RDWR 读、写打开
注:以上三个参数只指定一个,以下为其他可选项:
O_APPEND 每次写时都加到文件的尾端。
O_CREAT 若此文件不存在则创建它。使用此选择项时,需同时说明第三个参数mode,用其说明该新文件的存取许可权位。
O_EXCL 如果同时指定了O_CREAT,而文件已经存在,则出错。这可测试一个文件是否存在,如果不存在则创建此文件成为一个原子操作。
O_TRUNC 如果此文件存在,而且为只读或只写成功打开,则将其长度截短为0。
O_NOCTTY 如果pathname指的是终端设备,则不将此设备分配作为此进程的控制终端。
O_NONBLOCK 如果pathname指的是一个FIFO、一个块特殊文件或一个字符特殊文件,则此选择项为此文件的本次打开操作和后续的I/O操作设置非阻塞方式。
O_SYNC 使每次write都等到物理I/O操作完成。
参数:mode
常用0666(读4+写2=6),0表示为十进制数,第一个6=user,第二个6=group,第三个6=others
常用配置:

open(pathname, O_RDWR|O_CREAT|O_TRUNC, 0666) ;

3.2.creat()

  功能:创建一个文件

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int creat(const char *pathname, mode_t mode) ;
返回:若成功为只写打开的文件描述符,若出错为-1

参数如open()

3.3.close()

  功能:关闭一个打开的文件

#include <unistd.h>
int close (int filedes);
返回:若成功为0,若出错为-1

注:当一个进程终止时,它所有的打开文件都由内核自动关闭。很多程序都使用这一功能而不显式地用close()关闭打开的文件。
参数:filedes
文件描述符

3.4.lseek()

  功能:设置文件偏移量(类似文本输入的提示输入符),按系统默认,当打开一个文件时,除非指定O_APPEND选择项,否则该位移量被设置为0。

#include <sys/types.h>
#include <unistd.h>
off_t lseek(int filedes, off_t offset, int whence);
返回:若成功为新的文件位移,若出错为-1

参数:filedes
文件描述符
参数:offset
偏移量
参数:whence
SEEK_SET 距文件首设置偏移量
SEEK_CUR 距当前偏移量设置偏移量
SEEK_END 距文件尾设置偏移量

3.5.read()

  功能:从打开的文件读数据。

#include <unistd.h>
ssize_t read(int filedes, void *buff, size_t nbytes) ;
返回:读到的字节数,若已到文件尾为0,若出错为-1

参数:buff
读到的缓存区

3.6.write()

  功能:从打开的文件写数据。

#include <unistd.h>
ssize_t write(int filedes, const void * buff, size_t nbytes);
返回:若成功为已写的字节数,若出错为-1

3.7.dup()和dup2()

  功能:复制现存的文件描述符。

#include <unistd.h>
int dup(int filedes);
int dup2(int filedes, int filedes2) ;
两函数的返回:若成功为新的文件描述符,若出错为-1

注:由dup返回的新文件描述符一定是当前可用文件描述符中的最小数值。用dup2则可以用filedes2参数指定新描述符的数值。如果filedes2已经打开,则先将其关闭。如若filedes等于filedes2,则dup2返回filedes2,而不关闭它。

3.8.fcntl()

  功能:改变已经打开文件的性质。

#include <sys/types.h>
#include <unistd.h>
#include <fcntl.h>
int fcntl(int filedes, int cmd,.../* int arg * / ) ;
返回:若成功则依赖于cmd,若出错为-1

参数:cmd
复制一个现存的描述符(cmd=F_DUPFD)。
获得/设置文件描述符标记(cmd=F_GETFD或F_SETFD)。
获得/设置文件状态标志(cmd=F_GETFL或F_SETFL)。
获得/设置异步I/O有权(cmd=F_GETOWN或F_SETOWN)。·获得/设置记录锁(cmd=F_GETLK,F _SETLK或F_SETLKW)。

3.9.ioctl()

  功能:ioctl 函数是I/O操作的杂物箱。不能用本章中其他函数表示的I/O操作通常都能用ioctl表示。

#include <unistd.h> /* SVR4 */
#include <sys/ioctl.h> /* 4.3+*B /SD
int ioctl(int filedes, int request, . . . ) ;
返回:若出错则为-1,若成功则为其他值

详细见:https://blog.csdn.net/coolwriter/article/details/78242256

上一篇:Day006 方法的重载


下一篇:php-stream_context_create函数针对https请求处理