Linux 系统编程 开篇/ 文件的打开/创建

从本节开始学习关于Linux系统编程的知识!

学习Linux的系统编程有非常多的知识点,在应用层面,很重要的一点就是学习如何“用代码操作文件来实现文件创建,打开,编辑等自动化执行

那如何自动化实现对文件的创建,打开,编辑等呢?答案就是使用Linux系统提供的一系列API函数(如 open, write/read, lseek,close等等)。

Linux文件编程的一般步骤

总结一下就是,打开文件,以及读写操作之后关闭文件的操作都不是必不可少的。 

Linux 文件管理 

简单来说,现在学习的用户层面的操作就是给内核发送指令,让内核来驱动物理磁盘进行操作 

 

打开/创建文件

需要包含的头文件:

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

相关的API函数: 

int open(const char *pathname, int flags); //pathname是文件路径,flags是权限
int open(const char *pathname, int flags, mode_t mode);int creat(const char *pathname, mode_t mode);

open函数

当调用open打开一个文档之后,open函数会返回一个非负整数,这个整数就是文件描述符

如果对一个文档都进行了open,并返回了“2”,之后又想对其进行write,就是write(2)

如果返回为负数,则说明open失败!

也就是说,

文件标识符0可以指代键盘输入

文件标识符1可以指代键盘输出

且文件描述符只在当前进程有效!

参数说明

pathname

  • 要打开的文件名(含路径)

flags : 

  • O_RDONLY 只读打开
  • O_WRONLY 只写打开
  • O_RDWR 可读可写打开

当附带了权限后,打开的文件就只能按照这种权限来操作

以上这三个参数中应当只指定一个。下列参数是可选择的:

  • O_CREAT:若文件不存在则创建它。使用此选项时,需要同时说明第三个参数mode.用其说明该新文件的存取许可权限。
  • O_EXCL:以这种属性去打开文件时,如果同时指定了O_CREAT,而文件已经存在,则打开文件失败(也可以说返回值是-1)。
  • O_APPEND:以这种属性去打开文件时,每次写时都加到文件的尾端。(不想写入时文件被覆盖,用这个flag,正常写入没有加其他条件的话,原来文件中的数据内容会被覆盖,注意是覆盖,覆盖本身的字节长度,没有覆盖的会保留,不是删除)
  • O_TRUNC:以这种属性去打开文件时,如果这个文件中本来是有内容的, 而且为只读或只写成功打开,则将其长度截短为0,通俗点的意思就是把原来的文件中的内容删除,写入你自己要的数据内容
  • Mode:一定是在flags中使用了 O-CREAT 标志, mode 记录待创建的文件的访问权限

关于mode的值和权限的对应关系:

共有三种权限

  • 是否可读(r), 对应数字4
  • 是否可写(w), 对应数字2
  • 是否可执行(x), 对应数字1

共有三个权限分配的对象

  • 主用户
  • 同组用户
  • 其他组用户

比如:给的是0600时,则对应权限“-rw-------”,即只给主用户分配可读可写(4+2=6)的权限同组用户(第三位)和其他组用户(第四位)没有任何权限

除了0600这种表达方式,Linux也直接提供了一些宏来表示:

其中较为常用的是:

  • S_IRWXU:对主用户来说可读,可写,可执行
  • S_IRUSR:对主用户来说可读
  • S_IWUSR:对主用户来说可写
  • S_IXUSR:对主用户来说可执行

实操演示

1. 创建一个名为“FILE”的文件夹,将文件部分的学习代码都放进去,并在cmd中cd到FILE:

2. 使用touch指令创建一个新的文件:

关于touch指令,可以参考:

Linux命令之touch命令_touch linux_恒悦sunsite的博客-CSDN博客

3.  使用vi命令创建一个c文件:

关于vi模式下的一些操作,之前接触过,参考:

Linux 系统初识_mjmmm的博客-CSDN博客

4.  使用man命令查看open相关的函数:

man的使用参考:

Linux下的man命令_linux man命令_邓永豪的博客-CSDN博客

简单来说就是 “man + 函数对应的手册号 + 函数名” 其中手册号是1~9,常用前3个,实在不知道可以一个个试,手册号不加也没事

然后就可以看到对于open函数的描述,这样就方便在Linux系统里面直接查阅和复制

5. 编写demo1.c,然后保存退出:

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>int main()
{       int fd; // file descriptionfd = open("./file1",O_RDWR);printf("file description = %d\n",fd);return 0;
}       

 6. 运行demo1.c:

可见,我创建的文档“file1”被自动打开,并分配了文件描述符“3”

7. 此时,如果将 file1 删除,再执行一遍代码:

可见,返回-1,返回失败

O_CREAT参数的应用

在实际应用中,我如果不希望一个文件不存在就直接返回失败,那么可以在open函数中,添加上面提到的“O_CREAT”参数,就可以“若文件不存在则创建它”,并按要求增加“mode”参数:

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>int main()
{int fd; // file descriptionfd = open("./file1",O_RDWR|O_CREAT, 0600); //0600代表即将创建的文件“可读可写”printf("file description = %d\n",fd);return 0;
}

此时,在file1不存在的情况下open,依然会返回正常的文件标识符,并创建file1:

O_EXCL参数的应用

O_EXCL:以这种属性去打开文件时,如果同时指定了O_CREAT,而文件已经存在,则打开文件失败(也可以说返回值是-1)。

重写demo1.c:

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>int main()
{int fd; // file descriptionfd = open("./file1",O_RDWR|O_CREAT|O_EXCL, 0600);if(fd == -1){printf("fail to open, file already exit\n");}else{printf("file description = %d\n",fd);}return 0;
}

可见,当file1存在时,会返回-1,无法打开文件;只有将file1删除,才会正常返回文件标识符。 

O_APPEND参数的应用

O_APPEND:以这种属性去打开文件时,每次写时都加到文件的尾端。(不想写入时文件被覆盖,用这个flag,正常写入没有加其他条件的话,原来文件中的数据内容会被覆盖,注意是覆盖,覆盖本身的字节长度,没有覆盖的会保留,不是删除)

关于写入的操作,在下一节有介绍!

不加O_APPEND写入时:

使用demo2.c的代码执行两边,第二遍的时候,将写入的数据从“mjmmjm”改成“123”:

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>int main()
{int fd; // file descriptionchar *buf = "mjmmjm"; //第一遍char *buf = "123"; //第二遍fd = open("./file1",O_RDWR|O_CREAT, 0600);printf("file description = %d, open successfully!\n",fd);write(fd, buf, strlen(buf));close(fd); //close after writing return 0;
}

 

可见,如果没有添加O_APPEND,则第二次写入的数据会覆盖在原数据之上。

加入O_APPEND写入时:

依然使用demo2.c的代码执行两边,第二遍的时候,将写入的数据从“mjmmjm”改成“123”:

唯一的区别时这一次加上O_APPEND参数:

fd = open("./file1",O_RDWR|O_CREAT|O_APPEND, 0600);

可见,添加了O_APPEND了之后,就自动在文件末尾添加内容了。

O_TRUNC参数的应用

O_TRUNC:以这种属性去打开文件时,如果这个文件中本来是有内容的, 而且为只读或只写成功打开,则将其长度截短为0,通俗点的意思就是把原来的文件中的内容删除,写入你自己要的数据内容

在刚刚O_APPEND的实验中,file1的内容被修改成了“mjmmjm123”,现在修改demo2.c的代码,加入O_RRUNC参数,不删除file1的前提下编译运行 demo2.c:

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>int main()
{int fd; // file descriptionchar *buf = "new";fd = open("./file1",O_RDWR|O_CREAT|O_TRUNC, 0600);printf("file description = %d, open successfully!\n",fd);write(fd, buf, strlen(buf));close(fd); //close after writing return 0;
}

可见,文件的内容被完全替换成了新的写入内容,原来的内容全部被删除了。

creat函数

(需要添加的库在开头就说明了)

int creat(const char *pathname, mode_t mode);

参数说明

  • pathname:要打开的文件名(含路径)
  • mode:待创建的文件的访问权限

mode值的选择见上面的说明。

  • 返回值:文件标识符

creat函数的原型等价于 open(pathname,O_CREAT | O_TRUNC | O_WRONLY,mode);

其中,O_CREAT和O_TRUNC上面已经提到过,一个负责“文件不存在就创建它”,一个负责“每次写入就将之前内容全部删除”,最后一个O_WRONLY就是open函数中的flag参数,表示“只写打开

实操演示

修改demo1.c:

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>int main()
{int fd; // file descriptionfd = creat("./file2", S_IRWXU); //给主用户赋予可读可写可执行的权限if(fd == -1){printf("fail to open, file already exit\n");}else{printf("file description = %d\n",fd);}return 0;
}

可见,creat函数 在file2不存在的情况下,会自动创建,印证了creat函数天生就带有open函数中的O_CREAT功能。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/77999.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

GitHub上删除项目后,IDEA分享项目到GitHub提示Remote is already on GitHub

文章目录 一、错误信息二、解决方法1.删除GitHub上的项目2.找到项目里的.git隐藏文件3.找到config文件4.打开config文件&#xff0c;删除[remote "git-test"]及下面两行内容5.继续使用IDEA分享项目到GitHub即可 一、错误信息 二、解决方法 1.删除GitHub上的项目 2.…

整理mongodb文档:collation

文章连接 整理mongodb文档:collation 看前提示 对于mongodb的collation。个人主要用的范围是在createcollection&#xff0c;以及find的时候用&#xff0c;所以本片介绍的时候也是这两个地方入手&#xff0c;对新手个人觉得理解概念就好。不要求强制性掌握&#xff0c;但是要…

Flink CEP(三)pattern动态更新

线上运行的CEP中肯定经常遇到规则变更的情况&#xff0c;如果每次变更时都将任务重启、重新发布是非常不优雅的。尤其在营销或者风控这种对实时性要求比较高的场景&#xff0c;如果规则窗口过长&#xff08;一两个星期&#xff09;&#xff0c;状态过大&#xff0c;就会导致重启…

谈谈新能源技术

目录 1.什么是新能源 2.新能源的发展历程 3.新能源的优势 1.什么是新能源 新能源是指利用自然界可再生资源、无害的高效能资源或者核能等来替代传统能源的能源形式。与传统化石燃料相比&#xff0c;新能源具有更高的可持续性、更低的环境影响和更长久的供应。以下是一些常见的…

C++多线程环境下的单例类对象创建

使用C无锁编程实现多线程下的单例模式 贺志国 2023.8.1 在多线程环境下创建一个类的单例对象&#xff0c;要比单线程环境下要复杂很多。下面介绍在多线程环境下实现单例模式的几种方法。 一、尺寸较小的类单例对象创建 如果待创建的单例类SingletonForMultithread内包含的成…

openwr折腾记7-Frpc使用自主域名解析透传本地服务

FFrpc使用自主域名解析透传本地服务 综述frp透传服务结构流程-http服务域名透传 第一部分openwrt-frpc客户端配置和使用指定服务器指定规则在自己的域名运营商处添加域名解析 第二部分gpt3.5辅助shell编码实现frp自由切换服务器并更新dns解析获取切换服务器参数脚本实现切换 更…

Kubernetes(K8s)从入门到精通系列之十:使用 kubeadm 创建一个高可用 etcd 集群

Kubernetes K8s从入门到精通系列之十&#xff1a;使用 kubeadm 创建一个高可用 etcd 集群 一、etcd高可用拓扑选项1.堆叠&#xff08;Stacked&#xff09;etcd 拓扑2.外部 etcd 拓扑 二、准备工作三、建立集群1.将 kubelet 配置为 etcd 的服务管理器。2.为 kubeadm 创建配置文件…

postgresql表膨胀处理之pgcompacttable部署及使用

环境&#xff1a; 1&#xff09;redhat-release&#xff1a;CentOS Linux release 7.6.1810 (Core) 2&#xff09;database version&#xff1a;postgresql 14.6 一、添加pgstattuple pgcompacttable工具使用过程中需要依赖pgstattuple&#xff0c;因此需先添加pgstattuple…

服务器排查并封禁ip访问

前言 购买的服务器难免会遇到被攻击的情况&#xff0c;当我们发现服务器状态异常时&#xff0c;可以通过连接当前服务器的ip排查一下&#xff0c;并对可疑ip进行封锁禁止。我们可以通过路由跟踪来查看可疑ip。以下是两种解决方案。 解决方案 iptables netstat是一个用于监视…

spring总结

目录 什么是Spring? Spring的优缺点&#xff1f; 优点&#xff1a; 缺点&#xff1a; Spring IOC的理解 Spring AOP的理解 事务的边界为什么放在service层&#xff1f; Spring Bean的生命周期 什么是单例池&#xff1f;作用是什么&#xff1f; 单例Bean的优势 Bean…

企业微信小程序在调用wx.qy.login时返回错误信息qy.login:fail

原因是大概是绑定了多个企业但是在开发者工具中没有选择正确的企业 解决方法&#xff1a; 重新选择企业后即可成功获取code

《Zookeeper》从零开始学Zookeeper源码(二)之数据序列化与通信协议

目录 序列化与反序列化通信协议请求头的数据结构响应头的数据结构 序列化与反序列化 zookeeper的客户端与服务端、服务端与服务端之间会进行一系列的网络通信&#xff0c;在进行数据的传输过程中就涉及到序列化与反序列化&#xff0c;zookeeper使用Jute作为它的序列化组件&…

文字转语音

键盘获取文字&#xff0c;转化为语音后保存本地 from win32com.client import Dispatch from comtypes.client import CreateObject from comtypes.gen import SpeechLib speakerDispatch(SAPI.SpVoice) speaker.Speak(请输入你想转化的文字) datainput(请输入&#xff1a;)#s…

拥抱创新:用Kotlin开发高效Android应用

拥抱创新&#xff1a;用Kotlin开发高效Android应用 引言 在当今数字时代&#xff0c;移动应用已经成为人们生活中不可或缺的一部分。无论是社交媒体、电子商务还是健康管理&#xff0c;移动应用已经深刻地影响了我们的生活方式。随着移动设备的普及和功能的增强&#xff0c;A…

深入了解速卖通详情API:提升商品数据获取与处理效率

1. 速卖通详情API概述 速卖通详情API是通过接口方式获取商品详细信息的一种方法。它可以让开发者按需获取商品的标题、描述、价格、库存等详细数据&#xff0c;为后续的数据分析和处理提供基础。通过API&#xff0c;开发者可以实现自动化的商品数据管理&#xff0c;提高工作效…

jenkins准备

回到目录 jenkins是一个开源的、提供友好操作界面的持续集成(CI)工具&#xff0c;主要用于持续、自动的构建/测试软件项目、监控外部任务的运行。Jenkins用Java语言编写&#xff0c;可在Tomcat等流行的servlet容器中运行&#xff0c;也可独立运行。通常与版本管理工具(SCM)、构…

django bootstrap html实现左右布局,带折叠按钮,左侧可折叠隐藏

一、实现的效果 在django项目中,需要使用bootstrap 实现一个左右分布的布局,左侧区域可以折叠隐藏起来,使得右侧的显示区域变大。(为了区分区域,左右加了配色,不好看的修改颜色即可) 点击折叠按钮,左侧区域隐藏,右侧区域铺满: 二、实现思路 1、使用col-md属性,让左…

unity行为决策树实战详解

一、行为决策树的概念 行为决策树是一种用于游戏AI的决策模型&#xff0c;它将游戏AI的行为分解为一系列的决策节点&#xff0c;并通过节点之间的连接关系来描述游戏AI的行为逻辑。在行为决策树中&#xff0c;每个节点都代表一个行为或决策&#xff0c;例如移动、攻击、逃跑等…

助力618-Y的混沌实践之路 | 京东云技术团队

一、写在前面 1、混沌是什么&#xff1f; 混沌工程&#xff08;Chaos Engineering&#xff09;的概念由 Netflix 在 2010 年提出&#xff0c;通过主动向系统中引入异常状态&#xff0c;并根据系统在各种压力下的行为表现确定优化策略&#xff0c;是保障系统稳定性的新型手段。…

K8s中的ConfigMap

ConfigMap作用&#xff1a;存储不加密数据到etcd&#xff0c;让Pod以变量或者Volume挂载到容器中 场景&#xff1a;配置文件 3.以Vlolume挂载到Pod容器中