本文主要是介绍open、close以及creat函数,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
说明:只供学习交流,转载请注明出处
文件描述符:在Linux中,所有打开的文件都对应一个文件描述符,文件描述符本质是一个非负整数。
open函数:在对一个文件或设备进行读写前,都需要打开文件或设备,以获得该文件或设备的操作指针,也就是文件描述符。通过该信息可以完成文件或设备的读取、修改等操作。
open函数用于完成打开文件的操作,其具体信息如表所示:
open函数
头文件 | <sys/types.h> <sys/stat.h> <fcntl.h> | ||
函数形式 | int open(const char *pathname, int flags); int open(const char *pathname, int flags, mode_t mode); | ||
返回值 | 成功 | 失败 | 是否设置errno |
返回新的文件描述符 | -1 | 是 |
说明:open函数根据给定的文件名称,获得该文件的文件描述符。该文件描述符是一个非负整数。被用于read、write、lseek和fcntl函数中。open函数定义中的flag参数用于指定使用何种方式打开文件,而mode参数是用于指定文件读取权限。Flag参数中可以使用如下的信息:
O_RDONLY:以只读的方式打开文件。
O_WRONLY:以只写的方式打开文件。
O_RDWR:以读写方式打开文件。
O_APPEND:文件以添加的方式打开,也就是说,这时文件的指针位于文件结束位置。每次对文件的写操作都会将内容添加到文件的末尾。如果文件位于NFS文件系统上,多个进程同时添加数据到一个文件中可能会导致文件的损害,NFS文件系统不支持文件的添加操作。
O_ASYNC:支持文件读写的异步操作。
O_CREAT:如果指定的文件不存在,使用该参数时将创建新的文件。
O_DIRECT:在读写文件时使用最小的cache。通常情况下,这会带来文件读写性能的下降。但是如果程序自己处理了文件的读写缓存,这一参数还是有一定的作用的。
O_DIRECTORY:如果给出的路径名称不是一个目录的话,会导致打开失败。这一参数是Linux中特有的参数。
O_EXCL:与O_CREAT参数配合使用时,如果文件已经存在,open函数将调用失败。NFS文件系统不支持该参数。
O_LARGEFILE:支持大文件的打开。
O_NOATIME:从Linux 2.6.8内核开始,使用该参数可以使读取文件时,系统不会更新文件的最后访问时间。
O_TRUNC:如果文件已经存在,同时以读写文件方式打开文件的话,文件长度将被截取为0。如果文件是FIFO或终端设备文件,该参数将被忽略。
O_NONBLOCK:如果路径名指向FIFO/块文件/字符文件,则把文件的打开和后继I/O。
open函数中的mode参数支持如表所示。定义这些宏是为了更直观,当然也可以直接在程序中使用对应的八进制值。给出的权限同样要经过与umask值的运算才能得到最终的文件权限。
宏 | 八进制值 | 说明 |
S_IRWXU | 00700 | 文件所有者具有读、写及执行权限 |
S_IRUSR | 00400 | 文件所有者具有读权限 |
S_IWUSR | 00200 | 文件所有者具有写权限 |
S_IXUSR | 00100 | 文件所有者具有执行权限 |
S_IRWXG | 00070 | 文件用户组具有读、写及执行权限 |
S_IRGRP | 00040 | 文件用户组具有读权限 |
S_IWGRP | 00020 | 文件用户组具有写权限 |
S_IXGRP | 00010 | 文件用户组具有执行权限 |
S_IRWXO | 00007 | 其他用户具有读、写及执行权限 |
S_IROTH | 00004 | 其他用户具有读权限 |
S_IWOTH | 00002 | 其他用户具有写权限 |
S_IXOTH | 00001 | 其他用户具有执行权限 |
错误信息:
EACCES:没有访问文件的权限,给出的文件所处路径没有访问权限或文件不存在。
EEXIST:文件已经存在,同时使用O_CREAT和O_EXCL来打开文件。
EFAULT:路径名指向非法地址空间。
EISDIR:路径名指向一个目录,同时使用了写权限(O_WRONLY或O_RDWR)。
ELOOP:路径名中存在太多的符号链接。
EMFILE:进程打开文件达到上限。
ENAMETOOLONG:路径名过长。
ENFILE:系统达到打开文件数的上限。
ENODEV:路径名指向了一个不存在设备。
ENOENT:没有给出O_CREAT参数,而所打开的文件不存在。
ENOMEM:内核空间不足。
ENOSPC:没有空间创建新的文件。
ENOTDIR:给出的文件所处路径中含有不是目录的部分。
EOVERFLOW:路径给出的文件过大,无法打开。
实例:
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>int main(void)
{int fd;if ((fd = open("test", O_CREAT|O_EXCL| O_RDWR, 0777)) == -1){perror("Cannot create the test.txt file");return (1);}close(fd);
return (0);
}
close函数:
close函数用于关闭打开的文件或设备。只有调用close函数后,前面通过open函数打开文件或设备所占用的资源才会被释放。因此,在程序开发中,从资源释放的角度和程序安全上看,有必要养成在调用open函数后使用close函数释放资源的习惯。close函数的具体信息如下表:
close函数
头文件 | <unistd.h> | ||
函数形式 | int close(int fd); | ||
返回值 | 成功 | 失败 | 是否设置errno |
0 | -1 | 是 |
说明:close函数用于关闭打开的文件描述符。
错误信息:
EBADF:fd不是合法的文件描述符。
EINTR:close函数被信号中断。
EIO:发生读写错误。
实际上,上面那程序并不完善,在调用close函数时没有检查返回值。因为网络文件系统(如NFS文件系统)中,close函数的调用可能会因为网络延迟而失败。而且有些系统为提高读写速度,往往具有写后缓冲。也就是说,即使调用write函数成功的话,并不意味着数据已经写入磁盘,系统会在更合适的时候完成磁盘的写操作。如果关闭文件时不检查返回值,有可能导致在不知道的情况下数据丢失。
creat函数:
creat函数同样可以创建一个文件。该函数等同于open函数使用某些特殊参数下的调用。creat函数的具体信息如表所示:
头文件 | <sys/types.h> <sys/stat.h> <fcntl.h> | ||
函数形式 | int creat(const char *pathname, mode_t mode); | ||
返回值 | 成功 | 失败 | 是否设置errno |
返回新的文件描述符 | -1 | 是 |
说明:create函数等同于int open(const char *pathname,O_CREAT|O_WRONLY|O_TRUNC, mode_t mode)的形式。相关信息可以参考open函数。
错误信息:
参见open函数。
这篇关于open、close以及creat函数的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!