fopen open 讲解

1.来源:

open是UNIX系统调用函数(包括LINUX等),返回的是文件描述符(File Descriptor),它是文件在文件描述符表里的索引。
fopen是ANSIC标准中的C语言库函数,在不同的系统中应该调用不同的内核api。返回的是一个指向文件结构的指针。

**

2.函数原型

FILE *fopen(char *filename, char *mode);
int open(const char *path, int access, int mode);
注意返回值
**

3.文件IO层次

如果从文件IO的角度来看,前者属于低级IO函数,后者属于高级IO函数。低级和高级的简单区分标准是:谁离系统内核更近。低级文件IO运行在内核态,高级文件IO运行在用户态。

4.缓冲

缓冲文件系统
缓冲文件系统的特点是:在内存开辟一个“缓冲区”,为程序中的每一个文件使用;当执行读文件的操作时,从磁盘文件将数据先读入内存“缓冲区”,装满后再从内存“缓冲区”依此读出需要的数据。
非缓冲文件系统
缓冲文件系统是借助文件结构体指针来对文件进行管理,通过文件指针来对文件进行访问,既可以读写字符、字符串、格式化数据,也可以读写二进制数据。非缓冲文件系统依赖于操作系统,通过操作系统的功能对文件进行读写,是系统级的输入输出,它不设文件结构体指针,只能读写二进制文件,但效率高、速度快,由于ANSI标准不再包括非缓冲文件系统,因此建议大家最好不要选择它。open, close, read, write, getc, getchar, putc, putchar等。就是open无缓冲,fopen有缓冲。

5.关于参数

fopen函数

参数
filename – 这是 C 字符串,包含了要打开的文件名称。
mode – 这是 C 字符串,包含了文件访问模式,模式如下:
模式 描述
“r” 打开一个用于读取的文件。该文件必须存在。
“w” 创建一个用于写入的空文件。如果文件名称与已存在的文件相同,则会删除已有文件的内容,文件被视为一个新的空文件。
“a” 追加到一个文件。写操作向文件末尾追加数据。如果文件不存在,则创建文件。
“r+” 打开一个用于更新的文件,可读取也可写入。该文件必须存在。
“w+” 创建一个用于读写的空文件。
“a+” 打开一个用于读取和追加的文件。

rb:只读方式打开一个二进制文件(使用法则同r)。
rb+:可读可写方式打开一个二进制文件(使用法则同r+)。
wb:只写方式打开一个二进制文件(使用法则同w)。
wb+:可读可写方式生成一个二进制文件(使用法则同w+)。
ab:追加方式打开一个二进制文件(使用法则同a)。
ab+:可读可写方式追加一个二进制文件(使用法则同a+)。

open函数
函数原型:int open(const char *path, int access, int mode);
参数解释:
path:要打开的文件路径和名称。

对于以下可以使用fcntl()重新设置的只用(具体使用看fcnlt使用):
F_SETFL file set flag
F_SETFL命令允许更改的标志有O_APPEND,O_NONBLOCK,O_NOATIME,O_DIRECT,O_ASYNC
这个操作修改文件状态标记适用于以下场景:
文件描述符不是通过open()系统调用获得的。比如pipe()返回两个文件描述符代表管道的两端。socket()指向套接字。
int flag = fcntl(fd,F_GETFL);
flag |= O_APPEND;
fcntl(fd,F_SETFL,flag);//注意F_SETFL的时候是用3的参数的版本

access:访问模式,宏定义和含义如下:
– O_RDONLY(1):只读打开;
– O_WRONLY(2):只写打开;
– O_RDWR(4):读写打开;
还可选择以下模式与以上3种基本模式相与(只能开启其中一种):
– O_TEXT(0x4000)打开文本文件翻译CR-LF控制字符;
– O_BINARY(0x8000)打开二进制字符,不作CR-LF翻译;
– O_APPEND(0x0800):每次进行写操作时,内核都会先定位到文件尾,在执行写操作
– O_ASYNC:使用异步I/O模式
– O_CLOEXEC:在打开文件的时候,就为文件描述符设置FD_CLOEXEC标志。这是一个新的选项,用于解决在多线程下fork与用于fcntl设置FD_CLOEXEC的竞争。某些应用使用fork来执行第三方业务,为了避免泄露已打开文件的内容,那些文件会设置FD_CLOEXEC标志,但是fork与fcntl是两次调用,在多线程下,可能会在fcntl调用之前,就已经fork出子进程了,从而导致该文件句柄暴露给子进程
– O_CREAT(0x0100):当文件不存在的时候,就创建文件
– O_DIRECT:对该文件进行直接I/O,不使用VFS Cache
– O_DIRECTORY:要求打开的路径必须是目录
– O_EXCL(0x0400):该标志用于确保是此次调用创建的文件,需要与O_CREAT同时使用,当文件存在时,open函数返回失败
– O_LARGEFILE:表明文件为大文件
– O_NOATIME:读取文件时,不更新最后的访问时间
– O_NONBLOCK、O_NDELAY:将该文件描述符设置为非阻塞(默认都是阻塞的)
– O_SYNC:设置为I/O同步模式,每次进行写操作时都会将数据同步到磁盘,然后write才能返回
– O_TRUNC(0x0200):在打开文件的时候,将文件长度截断为0,需要与O_RDWR或– O_WRONLY同时使用。在写文件时,如果是作为新文件重新写入,一定要使用O_TRUNC标志,否则可能会造成旧内容依然存在于文件中的错误。

mode:该参数仅在access=O_CREAT方式下使用,其取值如下:
– S_IRUSR : 所有者拥有 读权限
– S_IWUSR : 所有者拥有 写权限
– S_IXUSR : 所有者拥有执行权限
等价:
– S_IREAD :可读;
– S_IWRITE :可写;
– S_IEXEC :可执行;

– S_IRGRP : 群组拥有读权限
– S_IWGRP : 群组拥有写权限
– S_IXGRP : 群组拥有执行权限

– S_IROTH : 其他用户拥有读权限
– S_IWOTH : 其他用户拥有写权限
– S_IXOTH : 其他用户拥有执行权限

– S_IFMT(0xF000):文件类型掩码;
– S_IFDIR(0x4000):目录;
– S_IFIFO(0x1000):FIFO 专用;
– S_IFCHR(0x2000):字符专用;
– S_IFBLK(0x3000):块专用;
– S_IFREG(0x8000):只为0x0000;

注意:
fd = open("/dev/buttons", O_RDWR ); //默认阻塞方式
fd = open("/dev/buttons", O_RDWR | O_NONBLOCK); //非阻塞方式打开
//针对文件系统的普通文件是无效的,同时select和poll函数也不适用监控普通文件。

参考:
https://www.cnblogs.com/sky-heaven/p/6985362.html#_label0
https://blog.csdn.net/LEON1741/article/details/78091974###
https://www.cnblogs.com/NickyYe/p/5497659.html

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值