Linux文件IO(一)-open使用详解

news/2024/9/19 12:22:04/ 标签: linux, java, dubbo

在 Linux 系统中要操作一个文件,需要先打开该文件,得到文件描述符,然后再对文件进行相应的读写操作(或其他操作),最后在关闭该文件;open 函数用于打开文件,当然除了打开已经存在的文件之外,还可以创建一个新的文件,函数原型如下所示:

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int open(const char *pathname, int flags);
int open(const char *pathname, int flags, mode_t mode);

在 Linux 系统下,可以通过 man 命令(也叫 man 手册)来查看某一个 Linux 系统调用的帮助信息,man命令可以将该系统调用的详细信息显示出来,譬如函数功能介绍、函数原型、参数、返回值以及使用该函数所需包含的头文件等信息;man 更像是一份帮助手册,所以也把它称为 man 手册,当我们需要查看某个系统调用的功能介绍、使用方法时,不用在上网到处查找,直接通过 man 命令便可以搞定,man 命令用法如下所示:

man 2 open    #查看 open 函数的帮助信息

Tips:man 命令后面跟着两个参数,数字 2 表示系统调用,man 命令除了可以查看系统调用的帮助信息外,还可以查看 Linux 命令(对应数字 1)以及标准 C 库函数(对应数字 3)所对应的帮助信息;最后一个参数 open 表示需要查看的系统调用函数名。

由于篇幅有限,此截图只是其中一部分内容,从图中可知,open 函数有两种原型?这是为什么呢?关于这个问题笔者一开始也不理解,大家都知道 C 语言是不支持重载的,那既然这样,只有一种解释了,那就是可变参函数;对于 C 语言中的可变参函数,对此不了解的朋友可以自行百度,本文档不作说明!

所以由此可知,在应用程序中调用 open 函数即可传入 2 个参数(pathname、flags)、也可传入 3 个参数(pathname、flags、mode),但是第三个参数 mode 需要在第二个参数 flags 满足条件时才会有效,稍后将对此进行说明;从图 2.3.1 可知,在应用程序中使用 open 函数时,需要包含 3 个头文件

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

函数参数和返回值含义如下:

**pathname:**字符串类型,用于标识需要打开或创建的文件,可以包含路径(绝对路径或相对路径)信息,譬如:"./src_file"(当前目录下的 src_file 文件)、"/home/dengtao/hello.c"等;如果 pathname 是一个符号链接,会对其进行解引用。

**flags:**调用 open 函数时需要提供的标志,包括文件访问模式标志以及其它文件相关标志,这些标志使用宏定义进行描述,都是常量,open 函数提供了非常多的标志,我们传入 flags 参数时既可以单独使用某一个标志,也可以通过位或运算(|)将多个标志进行组合。这些标志介绍如下:

以上给大家介绍了一些比较常用的标志,open 函数的 flags 标志并不止这些,还有很多标志这里并没有给大家进行介绍,譬如 O_APPEND、O_ASYNC、O_DSYNC、O_NOATIME、O_NONBLOCK、O_SYNC 以及 O_TRUNC 等,对于这些没有提及到的标志,在后面学习过程中,也会给大家慢慢介绍。对于初学者来说,我们需要把表 2.3.1 中所列出的这些标志给弄明白、理解它们的作用和含义。

Tips:不同内核版本所支持的 flags 标志是存在差别的,譬如说新版本内核所支持的标志可能在老版本

是不支持的,亦或者老版本支持的标志在新版本已经被取消、替代,man 手册中对一些标志是从哪个版本开始支持的有简单地说明,读者可以自行阅读!

前面我们说过,flags 参数时既可以单独使用某一个标志,也可以通过位或运算(|)将多个标志进行组合,譬如:

open("./src_file", O_RDONLY) //单独使用某一个标志
open("./src_file", O_RDONLY | O_NOFOLLOW |O_CREATE)  //多个标志组合

**mode:**此参数用于指定新建文件的访问权限,只有当 flags 参数中包含 O_CREAT 或 O_TMPFILE 标志时才有效(O_TMPFILE 标志用于创建一个临时文件)。权限对于文件来说是一个很重要的属性,那么在 Linux系统中,我们可以通过 touch 命令新建一个文件,此时文件会有一个默认的权限,如果需要修改文件权限,

可通过 chmod 命令对文件权限进行修改,譬如在 Linux 系统下我们可以使用"ls -l"命令来查看到文件所对应的权限。

当我们调用 open 函数去新建一个文件时,也需要指定该文件的权限,而 mode 参数便用于指定此文件

的权限,接下来看看我们该如何通过 mode 参数来表示文件的权限,首先 mode 参数的类型是 mode_t,这是一个 u32 无符号整形数据,权限表示方法如下所示:

我们从低位从上看,每 3 个 bit 位分为一组,分别表示:

O---这 3 个 bit 位用于表示其他用户的权限;

G---这 3 个 bit 位用于表示同组用户(group)的权限,即与文件所有者有相同组 ID 的所有用户;

U---这 3 个 bit 位用于表示文件所属用户的权限,即文件或目录的所属者;

S---这 3 个 bit 位用于表示文件的特殊权限,文件特殊权限一般用的比较少,这里就不给大家细讲了。

关于什么是文件所属用户、同组用户以及其他用户,这些都是 Linux 操作系统相关的基础知识,相信大家都理解这些概念;3 个 bit 位中,按照 rwx 顺序来分配权限位(特殊权限除外),最高位(权值为 4)表示读权限,为 1 时表示具有读权限,为 0 时没有读权限;中间位(权值为 2)表示写权限,为 1 时表示具有写权限,为 0 时没有写权限;最低位(权值为 1)表示执行权限,为 1 时表示具有可执行权限,为 0 时没有执行权限。接下来我们举几个例子(特殊权限这里暂时不管,其 S 字段全部为 0):

最高权限表示方法:

111111111(二进制表示)、777(八进制表示)、511(十进制表示);

最高权限这里意味着所有用户对此文件都具有读权限、写权限以及执行权限。

111000000(二进制表示):表示文件所属者具有读、写、执行权限,而同组用户和其他用户不具有任何权限;

100100100(二进制表示):表示文件所属者、同组用户以及其他用户都具有读权限,但都没有写、执行权限。Tips:open 函数 O_RDONLY、O_WRONLY 以及 O_RDWR 这三个标志表示以什么方式去打开文件,譬如以只写方式打开(open 函数得到的文件描述符只能对文件进行写操作,不能读)、以只读方式打开(open函数得到的文件描述符只能对文件进行读操作,不能写)、以可读可写方式打开(open 函数得到的文件描函数得到的文件描述符只能对文件进行读操作,不能写)、以可读可写方式打开(open 函数得到的文件描述符可对文件进行读和写操作);与文件权限之间的联系,只有用户对该文件具有相应权限时,才可以使用对应的标志去打开文件,否则会打开失败!譬如,我们的程序对该文件只有只读权限,那么执行 open 函数使用 O_RDWR 或 O_WRONLY 标志将会失败。关于文件权限等相关问题,将会在 4.1 中给大家介绍。

关于文件权限表示方法的问题,以上就给大家介绍这么多,在实际编程中,我们可以直接使用 Linux 中已经定义好的宏,不同的宏定义表示不同的权限,如下所示:

这些宏既可以单独使用,也可以通过位或运算将多个宏组合在一起,譬如:

S_IRUSR | S_IWUSR | S_IROTH

**返回值:**成功将返回文件描述符,文件描述符是一个非负整数;失败将返回-1。

以上就把 open 函数相关的基础知识给大家介绍完了,包括函数返回值、参数等信息,当然在后面的章节内容中,我们还会更加深入地给大家讲解 open 函数相关的知识点;接下来我们看一些 open 函数的简答使用示例。

open 函数使用示例

  • 使用 open 函数打开一个已经存在的文件(例如当前目录下的 app.c 文件),使用只读方式打开:
int fd = open("./app.c", O_RDONLY)
if (-1 == fd)return fd;
  • 使用 open 函数打开一个已经存在的文件(例如当前目录下的 app.c 文件),使用可读可写方式打开:
int fd = open("./app.c", O_RDWR)
if (-1 == fd)return fd;
  • 使用 open 函数打开一个指定的文件(譬如/home/dengtao/hello),使用可读可写方式,如果该文件是一个符号链接文件,则不对其进行解引用,直接返回错误:
int fd = open("/home/dengtao/hello", O_RDWR | O_NOFOLLOW);
if (-1 == fd)return fd;
  • 使用 open 函数打开一个指定的文件(譬如/home/dengtao/hello),如果该文件不存在则创建该文件,创建该文件时,将文件权限设置如下:

文件所属者拥有读、写、执行权限;

同组用户与其他用户只有读权限。

使用可读可写方式打开:

int fd = open("/home/dengtao/hello", O_RDWR | O_CREAT, S_IRWXU | S_IRGRP | S_IROTH);
if (-1 == fd)return fd


http://www.ppmy.cn/news/1527640.html

相关文章

最新EmlogPro影视主题模版/简约暗黑纯净Mould主题模板/博客网站源码

源码简介&#xff1a; 最新EmlogPro影视主题模版&#xff0c;它是一个简约暗黑纯净Mould主题模板&#xff0c;也能做博客网站源码。 Mould这个主题模板啊&#xff0c;真的是设计得特别有感觉。它的布局和设计都超级流畅&#xff0c;用起来特别直观&#xff0c;简单多了。不管是…

c++206 友元类

#include<iostream> using namespace std; class A { public://声明的位置 和public private无关friend void modifyA(A* pA, int _a);//函数modifyA是A的好朋友A(int a, int b){this->a a;this->b b;}int getA(){return this->a;} private:int a;int b; };vo…

力扣题解2332

大家好&#xff0c;欢迎来到无限大的频道。 今日继续给大家带来力扣题解。 题目描述&#xff08;中等&#xff09;​&#xff1a; 坐上公交的最晚时间 给你一个下标从 0 开始长度为 n 的整数数组 buses &#xff0c;其中 buses[i] 表示第 i 辆公交车的出发时间。同时给你一…

Spring Boot-Session管理问题

Spring Boot 中的 Session 管理问题及其解决方案 1. 引言 在 Spring Boot Web 应用中&#xff0c;Session 是用来维护用户状态的重要机制。由于 HTTP 协议本质上是无状态的&#xff0c;Session 提供了一种方式来存储和共享用户的会话数据。Spring Boot 提供了多种方式来管理 …

SpringMVC后续4

文件上传下载 导入maven <dependency><groupId>commons-fileupload</groupId><artifactId>commons-fileupload</artifactId><version>1.3.2</version></dependency> 配置MultipartResolver <bean id"multipartRes…

PointNet2(一)分类

发现PVN3D中使用到了pointnet2和 densfusion等网络&#xff0c;为了看懂pvn3d&#xff0c;因此得看看pointnet2&#xff0c;然而带cpp&#xff0c;cu文件的程序一时办事编译不成功&#xff0c;因此找到了一个 Pointnet_Pointnet2_pytorch-master&#xff0c;里面有pointnet和po…

孙怡带你深度学习(2)--PyTorch框架认识

文章目录 PyTorch框架认识1. Tensor张量定义与特性创建方式 2. 下载数据集下载测试展现下载内容 3. 创建DataLoader&#xff08;数据加载器&#xff09;4. 选择处理器5. 神经网络模型构建模型 6. 训练数据训练集数据测试集数据 7. 提高模型学习率 总结 PyTorch框架认识 PyTorc…

java-springboot 实现文件 图片的上传 以及渲染

在 Java Spring Boot 应用中实现文件和图片的上传以及渲染&#xff0c;通常涉及以下几个步骤&#xff1a; 配置文件上传&#xff1a;使用 Spring Boot 的 MultipartResolver 来配置文件上传。 创建上传接口&#xff1a;创建一个 REST 控制器来处理上传请求。 保存文件到服务器&…

C#基础(14)冒泡排序

前言 其实到上一节结构体我们就已经将c#的基础知识点大概讲完&#xff0c;接下来我们会讲解一些关于算法相关的东西。 我们一样来问一下gpt吧&#xff1a; Q:解释算法 A: 算法是一组有序的逻辑步骤&#xff0c;用于解决特定问题或执行特定任务。它可以是一个计算过程、一个…

linux-Shell 编程-常用 Shell 脚本技巧

Linux Shell 编程&#xff1a;常用 Shell 脚本技巧 一、概述 Shell 脚本是 Linux 系统管理员和开发人员日常自动化任务的重要工具。通过编写 Shell 脚本&#xff0c;用户可以自动化重复性工作、简化系统维护、管理服务器资源等。Shell 脚本的强大之处在于其简洁和灵活性&…

手势识别-Yolov5模型-自制数据集训练

1、源码下载&#xff1a; 大家可以直接在浏览器搜索yolov5即可找到官方链接&#xff0c;跳转进github进行下载&#xff1a; 这里对yolov5模型补充说明一下&#xff0c;它是存在较多版本的&#xff0c;具体信息可在master->tags中查看&#xff0c;大家根据需要下载。这些不同…

Golang如何优雅的退出程序

Golang如何优雅的退出程序 在 Go 中优雅地退出程序&#xff0c;通常需要处理一些清理工作&#xff0c;如关闭文件、网络连接、释放资源等。以下是一些常见的方法&#xff1a; 一、使用 os.Signal 和 signal.Notify 捕获系统信号&#xff1a;可以使用 os/signal 包来捕获中断…

Android中如何处理运行时权限?

在Android中&#xff0c;处理运行时权限是开发过程中一个至关重要的环节&#xff0c;它自Android 6.0&#xff08;API级别23&#xff09;引入&#xff0c;旨在提高用户隐私保护和应用的透明度。以下将详细阐述Android中处理运行时权限的方法、步骤、注意事项以及相关的最佳实践…

最优化理论与自动驾驶(十一):基于iLQR的自动驾驶轨迹跟踪算法(c++和python版本)

最优化理论与自动驾驶&#xff08;四&#xff09;&#xff1a;iLQR原理、公式及代码演示 之前的章节我们介绍过&#xff0c;iLQR&#xff08;迭代线性二次调节器&#xff09;是一种用于求解非线性系统最优控制最优控制最优控制和规划问题的算法。本章节介绍采用iLQR算法对设定…

使用阿里OCR身份证识别

1、开通服务 免费试用 2、获取accesskay AccessKeyId和AccessKeySecret 要同时复制保存下来 因为后面好像看不AccessKeySecret了 3.Api 参考 https://help.aliyun.com/zh/ocr/developer-reference/api-ocr-api-2021-07-07-recognizeidcard?spma2c4g.11186623.0.0.7a9f4b1e5C…

STM32快速复习(十二)FLASH闪存的读写

文章目录 一、FLASH是什么&#xff1f;FLASH的结构&#xff1f;二、使用步骤1.标准库函数2.示例函数 总结 一、FLASH是什么&#xff1f;FLASH的结构&#xff1f; 1、FLASH简介 &#xff08;1&#xff09;STM32F1系列的FLASH包含程序存储器、系统存储器和选项字节三个部分&…

AcWing算法基础课-789数的范围-Java题解

大家好&#xff0c;我是何未来&#xff0c;本篇文章给大家讲解《AcWing算法基础课》789 题——数的范围。本文详细解析了一个基于二分查找的算法题&#xff0c;题目要求在有序数组中查找特定元素的首次和最后一次出现的位置。通过使用两个二分查找函数&#xff0c;程序能够高效…

随机规划及其MATLAB实现

目录 引言 随机规划的基本模型 随机动态规划 随机动态规划建模实例​(随机动态规划)&#xff1a; MATLAB中的随机规划实现 示例&#xff1a;两阶段随机规划 表格总结&#xff1a;随机规划求解方法与适用场景 结论 引言 随机规划&#xff08;Stochastic Programming&…

VulhubDC-4靶机详解

项目地址 https://download.vulnhub.com/dc/DC-4.zip实验过程 将下载好的靶机导入到VMware中&#xff0c;设置网络模式为NAT模式&#xff0c;然后开启靶机虚拟机 使用nmap进行主机发现&#xff0c;获取靶机IP地址 nmap 192.168.47.1-254根据对比可知DC-4的一个ip地址为192.1…

C++——多态的原理

多态的原理 多态的原理引入虚函数表 多态的原理 引入 如下代码的输出结果为&#xff08;&#xff09; A.编译报错 B.运行报错 C.8 D.12 上⾯题⽬运⾏结果12bytes&#xff0c;除了_b和_ch成员&#xff0c;还多⼀个__vfptr放对象的前⾯(注意有些平台可能会放到对象的最后⾯&am…