【Linux】—— 在Linux上进行读写文件操作

前言:

  • 在之前,我已经对进程的相关知识进行了详细的介绍。本期开始,我们将要学习的是关于 “基础I/O”的知识!!!

目录

(一)C文件接口

 (二)系统文件I/O

1、接口介绍

2、代码示例

(三)总结


(一)C文件接口

首先,在正式进入本期主题之前,我先用C文件的接口带大家简单的回顾下,顺便带大家认识相关的接口函数等。

首先就是往文件里面进行写数据操作:

#include <stdio.h>
#include <string.h>#define LOG "log.txt"int main()
{FILE *fp = fopen(LOG , "w");if(!fp){perror("fopen");return 1;}const char *msg = "hello bit!\n";int count = 5;while(count--){//fputs(msg,fp);fwrite(msg, strlen(msg), 1, fp);}fclose(fp);return 0;
}

输出展示:

【解释说明】

  1. 上述代码简单的实现了打开文件、写入文本内容,并关闭文件。在系统中,提供了丰富的用于对文件进行操作的函数;
  2. 打开文件使用 fopen 函数以写入模式打开文件,返回一个文件指针 fp;
  3. 如果文件打开失败,perror 函数将输出错误信息到标准错误输出流。
  4. 其次使用fwrite函数将字符串msg通过文件指针fp写入文件(除了这个外还有很多)

首先就是读文件里面的数据操作:

#define LOG "log.txt"int main()
{FILE *fp = fopen(LOG, "r");if(!fp){perror("fopen");return -1;}//正常进行文件操作while(1){char line[128];if(fgets(line, sizeof(line), fp) == NULL) break;else printf("%s", line);}fclose(fp);return 0;
}

输出展示:

【解释说明】

  • 同样的对于读文件操作,在系统内部也提供的很多的函数去进行实现!

如上,是我们之前学的文件相关操作。还有 fseek ftell rewind 的函数。


 (二)系统文件I/O

操作文件,除了上述C接口(当然,C++也有接口,其他语言也有),我们还可以采用系统接口来进行文件访问.

先来直接以代码的形式,实现和上面一模一样的代码(写操作):

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>int main()
{umask(0);int fd = open("myfile", O_WRONLY|O_CREAT, 0644);if(fd < 0){perror("open");return 1;}int count = 5;const char *msg = "hello bit!\n";int len = strlen(msg);while(count--){write(fd, msg, len);//fd: 后面讲, msg:缓冲区首地址, len: 本次读取,期望写入多少个字节的数据。 //返回值:实际写了多少字节数据}close(fd);return 0;
}
  • C++中对文件进行读操作可写成下述:
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>int main()
{int fd = open("myfile", O_RDONLY);if(fd < 0){perror("open");return 1;}const char *msg = "hello bit!\n";char buf[1024];while(1){ssize_t s = read(fd, buf, strlen(msg));//类比writeif(s > 0){printf("%s", buf);}else{break;}}close(fd);return 0;
}

1、接口介绍

接下来,我首先带大家认识相关的接口。随后大家在来理解上述这两段代码!!

  • 最重要的当然是 open() ,通过对它的学习,我们将极大程度的理解有些知识

【解释说明】

参数

  • path:要打开的文件的路径字符串。
  • flags:打开文件的标志,可以使用一或多个以下标志的位或运算符 |

  第一个参数很好理解,对于第二个参数大家可能存在些疑惑我在这里重点讲讲关于这个标志的问题。

💨 首先,引入一个问题:OS是如何让用户给自己传递标志位的呢?

接下来,我给大家写个简单的 demo 样例帮助大家理解上述逻辑:

#include <stdio.h>#define ONE 0x1
#define TWO 0x2
#define THREE 0x4
#define FOUR 0x8
#define FIVE 0x10// 0000 0000 0000 0000 0000 0000 0000 0000
void Print(int flags)
{if(flags & ONE) printf("hello 1\n"); //充当不同的行为if(flags & TWO) printf("hello 2\n");if(flags & THREE) printf("hello 3\n");if(flags & FOUR) printf("hello 4\n");if(flags & FIVE) printf("hello 5\n");
}int main()
{printf("--------------------------\n");Print(ONE);printf("--------------------------\n");Print(TWO);printf("--------------------------\n");Print(FOUR);printf("--------------------------\n");Print(ONE|TWO);printf("--------------------------\n");Print(ONE|TWO|THREE);printf("--------------------------\n");Print(ONE|TWO|THREE|FOUR|FIVE);printf("--------------------------\n");return 0;
}

输出展示:

 【解释说明】

  1. 上述代码展示了使用位运算来模拟标志位。在这个示例中,每个标志位都表示一种不同的行为,当相应的位被设置时,相关的行为会执行;
  2. 首先,定义了一组宏来表示不同的标志位,每个标志位都对应一个唯一的二进制位。例如,ONE的二进制表示是:0000 0000 0000 0000 0000 0000 0000 0001TWO的二进制表示是:0000 0000 0000 0000 0000 0000 0000 0010,依此类推。
  3. 接下来,定义了一个Print函数,它接受一个整数参数flags,这个参数表示一组标志位的组合。在函数内部,使用位运算和按位与操作符&来检查每个标志位是否被设置。

有了上述认识,大家在返回去看 open() 函数中的 flags参数,我想就很明显了。当我们在man手册中往下面翻的时候就会看到如下内容:

  • 这一个个的选项就相当于宏,我们只需关于宏函数内部的意义即可!

2、代码示例

接下来,我们通过写代码的方式来进行理解!!

首先,有如下代码示例:

int main()
{int fd = open(LOG,O_WRONLY);if(fd == -1){printf("fd: %d, errno: %d, errstring: %s\n", fd, errno, strerror(errno));}else printf("fd: %d, errno: %d, errstring: %s\n", fd, errno, strerror(errno));close(fd);return 0;}

输出展示:

【解释说明】

  1. 上述代码的主要目的是打开一个文件并检查是否成功打开。如果打开失败,它将输出打开文件描述符(fd)、错误代码(errno)和错误字符串(strerror(errno));
  2. 然而,需要注意的是,因为开始并没有提供LOG这个文件,因此最后的输出肯定是发生报错。

解决方法就是在我们 open 的时候,再加上 【o_CREAT】这个标志:

输出展示:

然而,此时出现了一个奇怪的现象,我们通过查看得知 log.txt 文件的权限是处于乱码的情况:


因此,基于上述情况的出现。我们一般在用的时候一般不用 带两个参数的 open() ,而是用带三个参数的open() 函数

【解释说明】

  1. mode 是一个mode_t类型的参数,用于设置文件的权限;
  2. 它指定了文件的访问权限位,并且只有在使用O_CREAT标志创建文件时才会生效;
  3. 通常使用8进制表示权限位。例如,0644表示文件所有者具有读写权限,其他用户只有读权限。

基于上述情况,我们在后面加上相应的权限(我这里加的是0666):

输出展示: 

【解释说明】

  • 请注意,文件权限可能会受到操作系统的默认配置或其他因素的影响,即 umask;

  •  此时,系统默认的 umask 为2,因此在某些情况下,系统可能会对文件权限进行适当的修改,以使其符合操作系统的权限策略。

那么要如何保障这里的权限不受系统的影响呢?—— 我们可以自己设置

  • 此时,我们又需要引入一个新的函数:

接下来,我们对代码进行修改操作: 

输出展示:

【注意】

  • open 函数具体使用哪个,和具体应用场景相关,如目标文件不存在,需要open创建,则第三个参数表示创建文件的默认权限,否则,使用两个参数的open。

接下来,我们就需要往文件中写入数据了。在C++中,系统提供 write() 函数来进行写操作。

代码展示:

输出展示:


上述完成写入数据,接下来就是从文件中读出数据。在C++中,系统提供了 read() 函数

man手册查询:

代码展示:

输出展示:

【小结】

  • 有了上述这些认识,在回过头去看我给出的 读和写 的代码就容易了!

(三)总结

上面的 fopen fclose fread fwrite 都是C标准库当中的函数,我们称之为库函数(libc);


open close read write lseek 都属于系统提供的接口,称之为系统调用接口


回忆一下我们讲操作系统概念时,画的一张图:

  1. 根据上述图片,我们可以知道系统调用接口和库函数的关系,一目了然。
  2. 所以,可以认为,f#系列的函数,都是对系统调用的封装,方便二次开发。

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

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

相关文章

WebDAV之π-Disk派盘 + BubbleUPnP

BubbleUPnP是一款功能强大的Android播放器,支持UPnP/DLNA多屏互动。它可以将手机内容投屏到电视大屏上,与家人和朋友一起共享。此外,BubbleUPnP还提供了丰富的音乐和影视资源,您可以在线搜索并播放喜欢的内容。 以下是BubbleUPnP的一些主要特点: 1. 支持Chromecast和转码…

WebGL 绘制矩形

上一节绘制了圆点&#xff0c;调用的绘制方法如下&#xff1a;gl.drawArrays(gl.POINTS, 0, 1); 第一个参数明显是个枚举类型&#xff0c;肯定还有其他值&#xff0c;如下所示&#xff1a; POINTS 可视的点LINES 单独线段LINE_STRIP 线条LINE_LOOP 闭合线条TRIANGLES 单独三…

【题解】2596. 检查骑士巡视方案

题解&#xff1a; class Solution {int n,m;bool st[100][100];int flag;int dx[8]{-1,-2,-2,-1,1,2,2,1};int dy[8]{-2,-1,1,2,2,1,-1,-2}; public:bool checkValidGrid(vector<vector<int>>& grid) {m grid.size();n grid[0].size();dfs(grid,0,0,0);ret…

vue3中的吸顶导航交互实现 | VueUse插件

目的&#xff1a;浏览器上下滚动时&#xff0c;若距离顶部的滚动距离大于78px&#xff0c;吸顶导航显示&#xff0c;小于78px隐藏。使用vueuse插件中的useScroll方法​​​​​​​和动态类名控制进行实现 1. 安装 npm i vueuse/core 2. 获得滚动距离 项目中导入&#xff0…

在python程序中用windows的icon

这个exe的弹窗功能会使用到一个ico文件&#xff0c;如图&#xff1a; 用软件GreenfishIconEditorProPortable或者使用在线软件将你需要的图片制作成windows的icon 用程序将ico文件生成文本文件 import base64picture_name "logo.ico" open_pic open("%s…

【100天精通Python】Day56:Python 数据分析_Pandas数据清洗和处理(删除填充插值,数据类型转换,去重,连接与合并)

目录 数据清洗和处理 1.处理缺失值 1.1 删除缺失值&#xff1a; 1.2 填充缺失值&#xff1a; 1.3 插值&#xff1a; 2 数据类型转换 2.1 数据类型转换 2.2 日期和时间的转换&#xff1a; 2.3 分类数据的转换&#xff1a; 2.4 自定义数据类型的转换&#xff1a; 3 数…

神经反馈设备使用感受2:采集Muse的EEG原始数据(转自知乎)

神经反馈设备使用感受2&#xff1a;采集Muse的EEG原始数据 转自知乎&#xff0c;内容很好&#xff0c;怕之后找不到 想了一下&#xff0c;单写一部分来介绍一下Muse在数据采集方面的操作。同时也解释一下我自己的EEG数据是从哪里采集的。 关于Muse EEG数据的精度&#xff0c;在…

vue2实现自定义主题webpack-theme-color-replacer

需求&#xff1a;根据element的自定义主题色&#xff0c;之后改变element的全局所有颜色&#xff0c;解决页面刷新后主题色失效问题&#xff0c;这个需要把颜色存入到浏览器的存储中&#xff0c;如果换个浏览器就得重新选择了哈&#xff0c;如果需要在不同的浏览器保持一致的主…

将AI融入到SEO中—基于Python的实现思路

在当今数字化时代&#xff0c;搜索引擎优化&#xff08;SEO&#xff09;对于网站和在线业务的成功至关重要。然而&#xff0c;随着人工智能&#xff08;AI&#xff09;技术的迅猛发展&#xff0c;我们可以利用它来提升SEO策略并取得更好的效果。本文将介绍如何通过使用Python编…

分布式系统第五讲:分布式事务及实现方案

分布式系统第五讲&#xff1a;分布式事务及实现方案 事务是一个程序执行单元&#xff0c;里面的所有操作要么全部执行成功&#xff0c;要么全部执行失败。而分布式事务是指事务的参与者、支持事务的服务器、资源服务器以及事务管理器分别位于不同的分布式系统的不同节点之上。本…

【LeetCode: 1462. 课程表 IV:拓扑排序+图+广度优先搜索】

&#x1f680; 算法题 &#x1f680; &#x1f332; 算法刷题专栏 | 面试必备算法 | 面试高频算法 &#x1f340; &#x1f332; 越难的东西,越要努力坚持&#xff0c;因为它具有很高的价值&#xff0c;算法就是这样✨ &#x1f332; 作者简介&#xff1a;硕风和炜&#xff0c;…

现场直击 | 国台国标·中秋礼酒惊艳闪耀酒博会

以酒为媒&#xff0c;以酒会友。 9月9日&#xff0c;以“展示全球佳酿&#xff0c;促进开放合作”为主题的第12届中国&#xff08;贵州&#xff09;国际酒类博览会&#xff08;以下简称“贵州酒博会”&#xff09;在贵阳国际会议展览中心重磅开幕&#xff0c;本届贵州酒博会吸…

狼的传说小游戏

欢迎来到程序小院 狼的传说 玩法&#xff1a; 鼠标左键选择能防御、战斧、风暴3%、滚石10%、藤曼5%、冰柱5%、飞跃10%、三叶草20%、钢叉15%&#xff0c;消灭所有敌人&#xff0c;不同关卡不同敌人&#xff0c;快去闯关消灭敌人吧^^。开始游戏https://www.ormcc.com/play/gameS…

MySQL——读写分离

简介 读写分离&#xff0c;基本的原理是让主数据库处理事务性增、改、删操作&#xff08;INSERT、UPDATE、DELETE&#xff09;&#xff0c;而从数据库处理SELECT查询操作。数据库复制被用来把事务性操作导致的变更同步到集群中的从数据库。一般来说都是通过 主从复制&#xff…

得帆云“智改数转,非同帆响”-AIGC+低代码PaaS平台系列白皮书,正式发布!

5月16日下午&#xff0c;由上海得帆信息技术有限公司编写&#xff0c;上海市工业互联网协会指导的以“智改数转&#xff0c;非同帆响”为主题的《得帆云 AIGC低代码PaaS平台系列白皮书》正式在徐汇西岸国际人工智能中心发布。 本次发布会受到了上海市徐汇区政府、各大媒体和业内…

如何实现一个数据库的 UDF?图数据库 NebulaGraph UDF 功能背后的设计与思考

大家好&#xff0c;我是来自 BOSS直聘的赵俊南&#xff0c;主要负责安全方面的图存储相关工作。作为一个从 v1.x 用到 v3.x 版本的忠实用户&#xff0c;在见证 NebulaGraph 发展的同时&#xff0c;也和它一起成长。 BOSS直聘和 NebulaGraph 关于 NebulaGraph 在 BOSS直聘的应…

9.13 | day 6 |day 45| to 完全平方数

● 70. 爬楼梯 &#xff08;进阶&#xff09; class Solution {public int climbStairs(int n) {int[] dp new int[n1];//设置背包容量&#xff1a;n个int m 2;//有两个物品&#xff0c;注意这是一个完全背包问题dp[0] 1;//initialize ​for(int i 1;i<n;i){//遍历背包f…

快速幂 c++

一般大家写都是 int ans 1; for (int i 1; i < a; i )ans * x;时间复杂度 但是这对于我们还不够&#xff0c;我们要 首先我们得知道一个数学知识 那么求 就有以下递归式 a 能被2整除 a 不能被2整除 (这里a/2是整除) 所以每次都调用 不就是么 最后补充一个东西…

.net core 上传文件大小限制

微软官网文档中给的解释是.net core 默认上传文件大小限制是30M&#xff0c;所以即便你项目里没有限制&#xff0c;这里也有个默认限制。 官网链接地址 总结了一下解决办法&#xff1a; 1.首先项目里添加一个web.config自定义配置文件 在配置文件中加上这段配置 <!--//…

SQL 注入漏洞攻击

文章目录 1. 介绍2. 无密码登录3. 无用户名无密码登录4. 合并表获取用户名密码 1. 介绍 假设你用自己的用户名和密码登录了一个付费网站&#xff0c;网站服务器就会查询一下你是不是 VIP 用户&#xff0c;而用户数据都是放在数据库中的&#xff0c;服务器通常都会向数据库进行查…