当前位置: 首页 > news >正文

linux文件I/O之 open() 函数用法

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

typedef unsigned int mode_t ;

int open(const char *pathname, int flags);
int open(const char *pathname, int flags, mode_t mode);

函数功能

打开或创建一个文件

返回值

成功返回一个新的文件描述符(指代这个打开的文件),失败则返回 -1,并设置 errno 为相对应的错误标志

参数

pathname:路径名,标识要打开的文件(或目录)(例如:"./test.txt"、"/etc/passwd")

flags:位掩码,用于指定文件的打开模式。通过 O_RDONLY(只读)、O_WRONLY(只写) 或         O_RDWR(可读可写)中的其中一个打开文件的方式 与 下面的 0 个或多个可选模式按 位或(|) 操作得到。

flags说明
O_CREAT若文件不存在将创建它。
O_EXCL这个标志需要和 O_CREAT 结合在一起使用,表明如果参数 pathname 标识的文件已经存在,则打开失败,此时 errno 会被设置为 EEXIST。 换言之,这个标志确保 open() 函数就是创建新文件的。
O_NOCTTY如果参数 pathname 引用的是终端设备,O_NOCTTY 标志表明不将该设备分配作为此进程的控制终端设备。如果 pathname 引用的不是终端设备,则此标志无效。
O_TRUNC如果文件已经存在且为普通文件,而且打开模块又是写(即是以 O_WRONLY 或 O_RDWR 模式打开的),那么将清空文件的原有的所有内容,并将其长度设置为 0。若文件是 FIFO 或终端设备文件,此标志会被忽略。
O_APPEND每次写文件都追加到文件的尾端。(不会覆盖原有的内容)
O_NONBLOCK以非阻塞模式打开文件。
O_NDELAY以非阻塞模式打开文件,跟 O_NONBLOCK 是一样的,指向同一个标志位,推荐使用 O_NONBLOCK 标志,因为 O_NDELAY  是系统早期版本引入的,在读操作时,如果读不到数据,O_NDELAY会使 I/O 函数马上返回 0,但这又衍生出一个问题,因为读取到文件末尾(EOF)时返回的也是 0,这样无法区分是哪种情况。因此,O_NONBLOCK 就产生出来,它在读取不到数据时会回传 -1,并且设置 errno 为 EAGAIN。
O_SYNC以同步 I/O 方式打开文件,即每次 write 等待物理 I/O 操作完成,包括由该 write 操作引起的文件属性更新所需的 I/O 都操作完成。
O_LARGEFILE支持大文件模式打开文件,在 32 位操作系统中使用此标志,允许打开那些用 31 位都不能表示其长度的大文件。
O_DIRECTORY如果参数 pathname 不是目录,则打开失败,此时 errno 被设置为 ENOTDIR。
O_NOFOLLOW如果参数 pathname 引用的是一个符号链接,则 open() 函数打开失败,此时 errno 被设置为 ELOOP。
O_CLOEXEC将新打开的文件描述符设置 FD_CLOEXEC 标志,可以免去程序执行 fcntl() 函数时的 F_GETFD 和 F_SETFD 操作来设置 close-on-exec 标志的额外工作。

linux 内核中 <fcntl.h> 头文件对 O_NDELAY 的定义如下所示:

#ifndef O_NDELAY
#define O_NDELAY	O_NONBLOCK
#endif

在 linux 内核中 <fcntl.h> 头文件对参数 flags 所有有效取值如下所示:

/* list of all valid flags for the open/openat flags argument: */
#define VALID_OPEN_FLAGS \(O_RDONLY | O_WRONLY | O_RDWR | O_CREAT | O_EXCL | O_NOCTTY | O_TRUNC | \O_APPEND | O_NDELAY | O_NONBLOCK | O_NDELAY | __O_SYNC | O_DSYNC | \FASYNC	| O_DIRECT | O_LARGEFILE | O_DIRECTORY | O_NOFOLLOW | \O_NOATIME | O_CLOEXEC | O_PATH | __O_TMPFILE)

mode:位掩码,用于当调用 open() 函数创建新文件时,指定文件的访问权限。如果参数 flags 中没有指定 O_CREAT 标志,则可以省略 mode 参数。

mode 参数所有有效取值如下:

mode说明
S_ISUID执行时设置用户 ID
S_ISGID执行时设置组 ID
S_ISVTX粘着位,对目录使用
S_IRWXU用户可读,可写,可执行
S_IRUSR用户可读
S_IWUSR用户可写
S_IXUSR用户可执行
S_IRWXG组可读,可写,可执行
S_IRGRP组可读
S_IWGRP组可写
S_IXGRP组可执行
S_IRWXO其他用户可读,可写,可执行
S_IROTH其他用户可读
S_IWOTH其他用户可写
S_IXOTH

其他用户可执行

S_IRWXUGO

用户、同组用户以及其他用户都可读、可写、可执行

S_IRUGO

用户、同组用户以及其他用户都可读

S_IWUGO

用户、同组用户以及其他用户都可写

S_IXUGO

用户、同组用户以及其他用户都可执行

S_IALLUGO

以上列举的所有权限都有

在 linux 内核中 <sys/stat.h> 头文件对 mode 参数的有效取值定义如下所示:

#define S_ISUID  0004000
#define S_ISGID  0002000
#define S_ISVTX  0001000#define S_IRWXU 00700
#define S_IRUSR 00400
#define S_IWUSR 00200
#define S_IXUSR 00100#define S_IRWXG 00070
#define S_IRGRP 00040
#define S_IWGRP 00020
#define S_IXGRP 00010#define S_IRWXO 00007
#define S_IROTH 00004
#define S_IWOTH 00002
#define S_IXOTH 00001#define S_IRWXUGO	(S_IRWXU|S_IRWXG|S_IRWXO)
#define S_IALLUGO	(S_ISUID|S_ISGID|S_ISVTX|S_IRWXUGO)
#define S_IRUGO		(S_IRUSR|S_IRGRP|S_IROTH)
#define S_IWUGO		(S_IWUSR|S_IWGRP|S_IWOTH)
#define S_IXUGO		(S_IXUSR|S_IXGRP|S_IXOTH)

例子

以下程序功能:打开 "./log.txt" 文件,并往该文件内容的末尾写一行 "hello world\n"

#include <fcntl.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <stdlib.h>int main(int argc, char *argv[])
{int flags = O_WRONLY | O_CREAT | O_APPEND; /* 只写,没有该文件则创建,写时从文件内容的末尾附加新内容 */mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH; /* rw-rw-rw- */int fd = open("./log.txt", flags, mode); if (fd < 0) {perror("open error");exit(EXIT_FAILURE);}char buf[] = "hello world\n";ssize_t nwrite = write(fd, buf, strlen(buf));if (nwrite < 0) {perror("write error");exit(EXIT_FAILURE);}printf("write success\n");close(fd);return 0;
}

参考:

《UNIX环境高级编程》(第3版)

《Linux-UNIX系统编程手册》

http://www.lryc.cn/news/123355.html

相关文章:

  • 用Java操作MySQL数据库
  • SpringBoot启动报错:java: 无法访问org.springframework.boot.SpringApplication
  • Vue3 setup语法糖 解决富文本编辑器上传图片64位码过长问题 quill-image-extend-module
  • 百度坐标(BD09)、国测局坐标(火星坐标,GCJ02)、和WGS84坐标系之间的转换
  • 论文浅尝 | CI4MRC:基于因果推断去除机器阅读理解中的名字偏差
  • 【校招VIP】测试计划之黑盒测试白盒测试
  • 学习笔记整理-JS-01-语法与变量
  • PHP之PHPExcel
  • Redis系列(一):深入了解Redis数据类型和底层数据结构
  • javaScript:如何获取html中的元素对象
  • 面试总结-webpack/git
  • 深入解析美颜SDK:算法、效果与实现
  • ChatGPT Plus和ChatGPT对比
  • 计算机网络 运输层 TCP连接建立、释放
  • npm run xxx 的时候发生了什么?(以npm run dev举例说明)
  • 图解结构体大小和位域例子
  • 游戏行业实战案例 5 :玩家在线分布
  • TypeScript 关于对【泛型】的定义使用解读
  • 盛元广通食品药品检验检测实验室LIMS系统
  • 【数据结构】-- 栈和队列
  • 使用SpringAop切面编程通过Spel表达式实现Controller权限控制
  • Flutter:简单搞一个内容高亮
  • 2023/08/10
  • LeetCode 1289. 下降路径最小和 II:通俗易懂地讲解O(n^2) + O(1)的做法
  • Coin Change
  • 2023 8 -14链表OJ
  • 大数据必回之LSM树
  • Vue中的Object.defineProperty详解
  • MySQL高阶知识点(一)一条SQL【更新】语句是如何执行的
  • threejs实现模型gltf的动画效果