一、open函数
1、函数原型:int open(const char *path,int oflag,.../* mode_t mode */);
2、头文件:#include <fcntl.h>
3、参数说明:
(1)path:要打开或创建文件的名字;
(2)oflag:用下列一个或多个常量进行“或”运算构成oflag参数;
a、文件读写模式常量:
O_RDONLY:文件以只读方式打开;
O_WRONLY:文件以只写模式打开;
O_RDWR:文件以可读可写模式打开。
b、其他常用常量:
O_APPEND:追加模式打开,即当给已有文件进行写数据操作时,新数据会追加到原文件的末尾;
O_CREAT:若要操作的文件不存在,则会创建此文件,使用时需要同时指定第三个参数权限位;
O_EXCL:检测文件是否存在,若同时指定了O_CREAT,且文件存在,则会报错,若文件不存在,则创建此文件;
O_TRUNC:若文件存在,则在打开的同时会清空文件内容;
O_NOCTTY:若path引用的是终端设备,则不该将设备分配作为此进程的控制终端;
O_NONBLOCK:若path引用的是一个FIFO/一个块特殊文件/一个字符特殊文件,则此选项为文件的本次打开操作和后续的I/O操作设置为非阻塞模式。
c、同步输入输出:(目前没用到过,还不太清楚使用场景)
O_SYNC:使每次write等待物理I/O操作完成,包括由该write操作引起的文件属性更新所需的I/O;
O_DSYNC:使每次write要等待物理I/O操作完成,但若该写操作并不影响读取刚写入的数据,则不需要等待文件属性被更新;
O_RSYNC:使每一个以文件描述符作为参数进行的read操作等待,直至所有对文件同一部分挂起的写操作都完成。
4、示例:
1 #include <stdio.h> 2 #include <fcntl.h> 3 #include <unistd.h> 4 5 int main(int argc,char *argv[]) 6 { 7 int fd = open("test.txt",O_RDWR|O_CREAT|O_TRUNC,0777); 8 if (fd < 0) 9 perror("open"); 10 else 11 printf("fd = %d\n",fd); 12 13 close(fd); 14 15 return 0; 16 }
注意:open和close需要成对存在!
二、openat函数:
1、函数原型:int openat(int fd,const char *path,int oflag,.../* mode_t mode */);
2、头文件:#include <fcntl.h>
3、参数说明:
(1)fd:
相对于open函数,此函数多了一个fd参数,异同点如下:
a、若path指定的是绝对路径,fd参数被忽略,openat函数相当于open函数;
b、若path指定的是相对路径,fd参数指出了相对路径名在文件系统中的开始地址,fd参数是通过打开相对路径名所在的目录来获取;
c、path指定了相对路径名,fd参数具有特殊值AT_FDCWD.在此情况下,路径名在当前工作目录中获取,openat函数在操作上与open类似。
(2)其余参数与open一致,在此不重复。
4、使用示例:主要考虑fd的获取,打开目录一般是DIR *dirfp = opendir("./"),需要处理,考虑以下两种方式;
(1)利用 dirfd()函数将opendir返回的目录描述符转为int类型的文件描述符;
函数原型:int dirfd(DIR *dirp);
示例:
1 #include <sys/types.h> 2 #include <sys/stat.h> 3 #include <fcntl.h> 4 #include <dirent.h> 5 #include <stdio.h> 6 #include <unistd.h> 7 8 int main() 9 { 10 DIR *dir; 11 int dirfd2; 12 int fd; 13 int n; 14 15 dir = opendir("./"); 16 if(NULL == dir) 17 { 18 perror("open dir error"); 19 return -1; 20 } 21 dirfd2 = dirfd(dir); 22 if(-1 == dirfd2) 23 { 24 perror("dirfd error"); 25 return -1; 26 } 27 28 fd = openat(dirfd2,"output.log",O_CREAT|O_RDWR|O_TRUNC,0777); 29 if(-1 == fd) 30 { 31 perror("opeat error"); 32 return -1; 33 } 34 n = write(fd,"Hello world!\n",15); 35 36 close(fd); 37 closedir(dir); 38 39 return 0; 40 41 }
(2)直接用open打开一个目录,其返回值作为openat的第一个参数:
示例:
1 #include <stdio.h> 2 #include <sys/stat.h> 3 #include <fcntl.h> 4 #include <stdlib.h> 5 #include <unistd.h> 6 7 void creat_at(char *dir_path, char *relative_path) 8 { 9 int dir_fd; 10 int fd; 11 12 dir_fd = open(dir_path, O_RDONLY); 13 if (dir_fd < 0) 14 { 15 perror("open"); 16 exit(EXIT_FAILURE); 17 } 18 19 fd = openat(dir_fd, relative_path, O_CREAT | O_TRUNC | O_RDWR, 0777); 20 if (fd < 0) 21 { 22 perror("openat"); 23 exit(EXIT_FAILURE); 24 } 25 26 write(fd, "HELLO\n", 6); 27 28 close(fd); 29 close(dir_fd); 30 } 31 32 int main() 33 { 34 creat_at("./", "log.txt"); 35 return 0; 36 }