文件I/O——文件打开函数(open/openat)


一、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 }

 


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM