##aio
struct aiocb {
int aio_fildes; /* 文件描述符 */
off_t aio_offset; /* 文件偏移 */
volatile void *aio_buf; /* 缓冲区地址 */
size_t aio_nbytes; /* 传输的数据长度 */
struct sigevent aio_sigevent; /* 通知方法 */
int aio_lio_opcode; /* 仅被 lio_listio() 函数使用 */
/*未示出的各种实现内部字段*/
};
aio_lio_opcode
LIO_READ lio操作类型为异步读
LIO_WRITE; lio操作类型为异步写
###编译时要加 -lrt 这个库
##int aio_read(struct aiocb *aiocbp);
请求对一个有效的文件描述符进行异步读操作,这个文件描述符可以表示一个文件、套接字甚至管道
aio_read函数在请求进行排队之后会立即返回,执行成功返回0,出错返回-1,并设置errno的值
###int aio_write(struct aiocb *aiocbp);
aio_write函数用来请求一个异步的写操作
aio_write函数会立即返回,具体与aio_read相同
### int aio_error(struct aiocb * aiocbp);
用来确定请求状态
如果该函数返回0,表示aiocbp指定的异步I/O操作请求完成。
EINPROGRESS:说明请求尚未完成
ECANCELLED:说明请求被应用程序取消
如果该函数返回-1,表示发生错误,检查errno。
### ssize_ t aio_return(struct aiocb *aiocbp);
这个函数的返回值相当于同步I/O中,read/write的返回值。只有在aio_error调用后才能被调用。
#####此函数只有在aio_error调用确定请求已经完成之后才会调用这个函数
###int aio_suspend(const struct aiocb *const cblist[],int n,const struct timespec *timeout);
aio_suspend函数可以时当前进程挂起,直到有向其注册的异步事件完成为止
阻塞
当有AIO请求返程后,该函数返回
###int aio_cancel(int fd,struct aiocb *aiocb);
取消在文件描述符fd上的aiocb所指定的异步I/O请求。
如果该函数返回AIO_CANCELED,表示操作成功。
如果该函数返回AIO_NOTCANCELED,表示取消操作不成功,使用aio_error检查一下状态。
如果返回-1,表示发生错误,检查errno.
###int lio_listio(int mode,struct aiocb *list[],int nent,struct sigevent *sig);
listio函数可以用于同时发起多个请求(很重要),它使得用户可以在一个系统调用中启动大量的I/O操作。
参数介绍:
mode参数
LIO_WAIT会阻塞这个调用,直到所有的I/O都完成为止
LIO_NOWAIT立即返回
list是aiocb的引用列表
nent最大元素个数
##文件状态结构体
struct stat {
dev_t st_dev; // 文件所在设备ID
ino_t st_ino; // 结点(inode)编号
mode_t st_mode; // 用于模式检查
nlink_t st_nlink; // 硬链接个数
uid_t st_uid; // 所有者用户ID
gid_t st_gid; // 所有者组ID
dev_t st_rdev; // 设备ID(如果是特殊文件)
off_t st_size; // 总体尺寸,以字节为单位
blksize_t st_blksize; // 文件系统 I/O 块大小
blkcnt_t st_blocks; // 已分配 512B 块个数
time_t st_atime; // 上次访问时间
time_t st_mtime; // 上次更新时间
time_t st_ctime; // 上次状态更改时间
};
##常见宏
S_ISLNK(st_mode):是否是一个连接.
S_ISREG(st_mode):是否是一个常规文件.
S_ISDIR(st_mode):是否是一个目录
S_ISCHR(st_mode):是否是一个字符设备.
S_ISBLK(st_mode):是否是一个块设备
S_ISFIFO(st_mode):是否 是一个FIFO文件.
S_ISSOCK(st_mode):是否是一个SOCKET文件
###int fstat(int filedes, struct stat *buf);
通过文件描述符 获取文件对应的属性。
###int lstat(const char *restrict pathname, struct stat *restrict buf);
连接文件描述命,获取文件属性
###int stat(const char *path,struct stat *buffer);
提供文件名字,获取文件对应属性。
参数:
path 文件或者文件夹的路径
buffer 获取的信息保存在内存中
返回值:
正确——返回0
错误——返回-1,具体错误码保存在errno中
restrict是c99标准引入的,它只可以用于限定和约束指针,并表明指针是访问一个数据对象的唯一且初始的方式.
###int access(const char *pathname,int mode);
判断文件是否存在和是否可读可写
pathname:是文件名称
mode是我们要判断的属性.可以取以下值或者是他们的组合:
R_OK文件可以读
W_OK文件可以写
X_OK文件可以执行
F_OK文件存在.
当我们测试成功时,函数返回0,否则如果有一个条件不符时,返回-1.
###int mkdir(const char *path, mode_t mode);
参数:
path是目录名
mode是目录权限
返回值:
返回0 表示成功, 返回 -1表示错误,并且会设置errno值。
mode模式位:
mode 表示新目录的权限,可以取以下值:
S_IRUSR 用户读权限
S_IWUSR 用户写权限
S_IXUSR
S_IRWXU This is equivalent to (S_IRUSR | S_IWUSR | S_IXUSR).
S_IRGRP 用户组读权限.
S_IWGRP 用户组写权限.
S_IXGRP Execute or search permission bit for the group owner of the file. Usually 010.
S_IRWXG This is equivalent to (S_IRGRP | S_IWGRP | S_IXGRP).
S_IROTH 其他组读权限
S_IWOTH 其他组写权限
S_IXOTH Execute or search permission bit for other users. Usually 01.
S_IRWXO This is equivalent to (S_IROTH | S_IWOTH | S_IXOTH).
S_ISUID This is the set-user-ID on execute bit, usually 04000. See How Change Persona.
S_ISGID This is the set-group-ID on execute bit, usually 02000. See How Change Persona.
S_ISVTX This is the sticky bit, usually 01000.
S_IREAD
S_IWRITE
S_IEXEC
##文件树遍历
int nftw(const char *dirpath,
int (*fn) (const char *fpath,
const struct stat *sb,
int typeflag,
struct FTW *ftwbuf),
int nopenfd,
int flags);
dirpath:
遍历此下面的目录树,为每个树的节点调用一次fn()。默认情况下,当前目录总是先于其包含的文件和子目录被处理(先序遍历)。
fn:
fpath: 节点的路径名
sb: 为fpath调用stat函数所返回的指向stat结构体的指针
typeflag:
FTW_F fpath是一个普通文件。
FTW_D fpath是一个目录。
FTW_DNR fpath是一个不能被读的目录。
FTW_DP fpath是一个目录,并且 flag参数被指定为FTW_DEPTH。
(如果flags没有被指定为TW_DEPTH,那么访问目录时使用的typeflag总会是FTW_D。)路径fpath下的所有文件和子目录已经被处理过了。
FTW_NS 在不是符号链接的fpath上调用stat失败。可能的原因是调用者对父目录有读权限,所以文件名fpath可以被看到,但是没有执行权限,所以执行stat失败。由sb指向的缓存的内容是未定义的。
FTW_SL fpath是一个符号链接,flags被设置为FTW_PHYS。
FTW_SLN fpath是一个指向不存在的文件的符号链接。(只在FTW_PHYS未被设置的时候才会发生。)
ftwbuf:
struct FTW
{
int base; 在fpath中给定的路径名中的文件名的偏移量。
int level; fpath在目录树中相对于根节点的深度。
};
nopenfd:
nftw() 能够同时打开目录的最大数量。当搜索深度超过这个值,nftw() 将会变慢
flags:
FTW_ACTIONRETVAL (从 glibc 2.3.3开始支持)
如果这个特定的glibc的flag被设置,nftw() 会对从fn()返回的值进行不同处理。fn() 应该返回下面的值的其中一个:
FTW_CONTINUE 让nftw() 继续正常进行。
FTW_SKIP_SIBLINGS 如果fn() 返回这个值,当前节点的兄弟节点会被跳过,处理从父节点继续进行。
FTW_SKIP_SUBTREE 如果一个目录节点调用fn()(typeflag是FTW_D),这个返回值会阻止这个目录下的对象作为参数传递给fn()。nftw() 继续处理当前目录的下一个兄弟节点。
FTW_STOP 这会导致nftw() 立即返回FTW_STOP。
其它返回值可以关联到未来的一些新的行为上;fn() 不应该返回除上面列出的值之外的其它值。
为了从<ftw.h>中获取FTW_ACTIONRETVAL的定义,必须在Include任何头文件之前定义功能测试宏 _GNU_SOURCE。
FTW_CHDIR
如果设置了这个flag,在处理每个目录的内容之前,都会chdir(2)到这个目录。如果程序需要在fpath所在的某个目录做一些操作,这就是有用的。(指定这个flag不会对作为fn 参数fpath进行传递的路径名有影响。)
FTW_DEPTH
设置这个flag会进行后序遍历,也就是在处理完当前目录的内容和它的所有子目录之后才会调用fn() (默认情况下,每个目录在它的内容之前被处理。)
FTW_MOUNT
设置这个flag,就会停留在同一个文件系统中(也就是不会跨越挂载点)。
FTW_PHYS
设置这个flag,就不会跟随符号链接。(这是你想做的。)如果不设置这个flag,就会跟随符号链接,但是没有文件会被报告两次。
如果FTW_PHYS没有被设置,但是设置了FTW_DEPTH,那么函数fn() 就永远不会被自己是自己子孙的目录调用到。
成功返回0,失败返回-1.
###size_t getpagesize(void);
函数说明:返回一分页的大小,单位为字节(byte)。此为系统的分页大小,不一定会和硬件分页大小相同。
返回值:内存分页大小。
谁知道这个函数有什么鬼用!!!
###int posix_fadvise(int fd, off_t offset, off_t len, int advice);
预先声明对文件数据的访问模式
advice:
POSIX_FADV_NORMAL
表示该应用程序没有建议提供有关其指定的数据访问模式。如果没有意见,给出了一个打开的文件,这是默认的假设。
POSIX_FADV_SEQUENTIAL
该应用程序需要访问指定的数据顺序(与以前高的人读低偏移)。
POSIX_FADV_RANDOM
将指定的数据将会以随机顺序进行访问。
POSIX_FADV_NOREUSE
将指定的数据将只访问一次。
POSIX_FADV_WILLNEED
将指定的数据将在不久的将来访问。
POSIX_FADV_DONTNEED
指定的数据不会在短期内被访问。
###int fallocate(int fd, int mode, off_t offset, off_t len);
为文件预分配物理空间。