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

Linux系统编程 - 基础IO(IO操作)

目录

预备知识

复习C文件IO相关操作

printf相关函数

fprintf

snprintf

读取文件

系统文件IO操作

open函数

umask()函数

open函数返回值

预备知识

1.你真的理解文件原理和操作了吗?不是语言问题,是系统问题
2.是不是只有C/C++有文件操作呢? 不是,Java,python,go都有,他们的文件操作方法是不一样的?如何处理这种现象呢? 有没有一种统一的视角,看待所有的语言文件从操作呢?
3.操作文件的时候,第一件事情,就是打开文件,打开文件时做什么呢?如何理解呢?
4.文件 = 内容 + 属性 -> 针对文件的操作,对内容的操作,对属性的操作
5.当文件没有被操作的时候,文件一般会在什么位置磁盘
6.当我们对文件进行操作的时候,文件需要在哪里 内存,为什么呢? 因为CPU和内存交互
7.当我们对文件进行操作的时候,文件需要提前被load到内存,load是内容还是属性属性,因为一个文件至少得有属性
8.当我们对文件进行操作的时候,文件需要提前被load到内存,是不是只有你一个人在load呢?不是,内存中一定存在大量的不同文件的属性
9.所以综上,打开文件本质就是将需要的文件属性加载到内存中,OS内部一定会同时存在大量的被打开的文件,那么操作系统要不要管理这些被打开的文件呢? 要,OS需要先描述,在组织。
先描述,构建在内存中的文件结构体struct file{struct file* next},就可以从磁盘来,被打开的文件
a.每一个被打开的文件,都要在OS内对应文件对象的struct结构体,可以将所有的struct file结构体用某种数据结构链接起来--,在OS内部,对被打开的文件进行管理,就被转换成为了对链表的增删查改。
结论:文件被打开,OS要为被打开的文件,创建对应的内核数据结构
struct file
{
//各种属性
//各种链接关系
}
10.文件其实可以被分开两大类:磁盘文件,被打开的文件(内存文件)
11.文件被打开,是谁打开呢?OS,但是是谁让OS打开的呢?用户(进程为代表的)
12.我们之前的所有的文件操作,都是进程和被打开文件的关系
13.都是进程和被打开文件的关系:struct stak_structstruct file

复习C文件IO相关操作

下面是用C语言实现对文件log.txt进行操作:

#include <stdio.h>
#define LOG "log.txt"int main()
{// w:默认写方式打开文件,如果文件不存在,就创建它// 默认如果只是打开,文件内容会自动被清空// 同时,每次进行写入的时候,都会从最开始进行写入FILE *fp = fopen(LOG, "w");if (fp == NULL){perror("fopen fail");return 1;}// 正常进行文件操作const char *msg = "hello linux\n";int cnt = 5;while (cnt){fputs(msg, fp);cnt--;}fclose(fp); // 关闭文件return 0;
}

成功创建了log.txt文件,打开文件

printf相关函数

printf 默认是向显示器读取

int main()
{// w:默认写方式打开文件,如果文件不存在,就创建它// 1. 默认如果只是打开,文件内容会自动被清空// 2. 同时,每次进行写入的时候,都会从最开始进行写入FILE *fp = fopen(LOG, "w");if (fp == NULL){perror("fopen fail");return 1;}// 正常进行文件操作const char *msg = "hello linux";int cnt = 5;while (cnt){fprintf(fp, "%s:%d:phw\n", msg, cnt);cnt--;}fclose(fp); // 关闭文件return 0;
}

fprintf

fprintf(stdout, "%s:%d:phw\n", msg, cnt); // Linux一切皆文件,stdout也对应一个文件,显示器文件

snprintf

写入到buffer缓冲里

下面测试一下将msg改成phw

这里得出结论, “w"为覆盖式写入

追加式写入"a"选项

读取文件

系统文件IO操作

open函数

pathname: 要打开或创建的目标文件

flags: 打开文件时,可以传入多个参数选项,用下面的一个或者多个常量进行“或”运算,构成flags。
参数:
 O_RDONLY: 只读打开
 O_WRONLY: 只写打开
 O_RDWR : 读,写打开
 这三个常量,必须指定一个且只能指定一个
 O_CREAT : 若文件不存在,则创建它。需要使用mode选项,来指明新文件的访问权限
 O_APPEND: 追加写

 O_TRUNC:清空文件内容
返回值:
 成功:新打开的文件描述符
 失败:-1

下面是标志位的举例程序:

#define ONE 0x1
#define TWO 0x2
#define THREE 0x4
#define FOUR 0X8
#define FIVE 0X10void 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");printf(ONE);printf("-------------------\n");printf(TWO);printf("-------------------\n");printf(FOUR);printf("-------------------\n");printf(ONE | TWO);printf("-------------------\n");printf(ONE|TWO|THREE);printf("-------------------\n");printf(ONE|TWO|THREE|FOUR|FIVE);printf("-------------------\n");return 0;
}

 

open函数测试:

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#define LOG "log2/txt"// 系统方案
int main()
{int fd = open(LOG, O_WRONLY);printf("fd:%d\n", fd);return 0;
}

文件不存在

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
#include <errno.h>
#define LOG "log2/txt"// 系统方案
int main()
{int fd = open(LOG, O_WRONLY |O_CREAT);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;
}

我们在使用open函数的时候不仅要O_WRONLY (写)还要创建O_CREAT

但是这种方式创建的文件,是没有权限的。

其中参数mode就是权限

因为umask默认权限的原因

umask()函数

umask() 函数的参数为一个八进制数,它的每一位分别表示对应的文件权限是否会被屏蔽掉,例如,umask(022) 表示屏蔽掉写入权限和执行权限。

umask(0)这意味着没有任何权限被屏蔽掉。

 将mask初始化为0

 

 成功将文件的权限设置成自己想要的

wirte()函数

 

 这里的strlen不需要+1,\0是C语言的规定,不是文件的规定,\0会被解释成乱码

O_WRONLY | O_CREAT 默认不会对原始文件内容做清空,需要加上O_TRUNC

 O_APPEND | O_CREAT 不会追加写,需要加上O_WRONLY

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#define LOG "log.txt"// 系统方案
int main()
{umask(0);int fd = open(LOG, O_RDONLY, 0666);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));}char buffer[1024];// 这里无法做到按行读取,我们是整体读取的ssize_t n = read(fd, buffer, sizeof(buffer) - 1); //使用系统接口来进行IO的时候,一定要注意\0的问题if (n > 0){buffer[n] = '\0';printf("%s\n", buffer);}close(fd);return 0;
}

 

open函数返回值

在认识返回值之前,先来认识一下两个概念: 系统调用库函数

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

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

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

 系统调用接口和库函数的关系,一目了然。 所以,可以认为,f系列的函数,都是对系统调用的封装,方便二次开发

相关文章:

Linux系统编程 - 基础IO(IO操作)

目录 预备知识 复习C文件IO相关操作 printf相关函数 fprintf snprintf 读取文件 系统文件IO操作 open函数 umask()函数 open函数返回值 预备知识 1.你真的理解文件原理和操作了吗&#xff1f;不是语言问题&#xff0c;是系统问题2.是不是只有C/C有文件操作呢&#x…...

基于 Avue 的 CRUD 表格组件封装

在 components 文件夹中,创建一个新的 .vue 文件,例如:AvueCrudTable.vue。 透传父组件传递的属性和事件 : 1、利用v-bind=“ a t t r s " 支持所有 a v u e 的使用方法并在其基础上进行封装 2 、使用 v − o n = " attrs"支持所有 avue 的使用方法并在其基…...

树莓派学习笔记(十三)基于框架编写驱动代码

文章目录一、代码分析&#xff1a;二、源码一、代码分析&#xff1a; 在内核中由于代码文件多&#xff0c;避免函数名重复&#xff0c;使用static将函数的作用域限制在该文件内 内核的打印函数printk和printf类似 file_operations结构体使用符号“ . ”指定参数&#xff0c;省…...

vue事件修饰符之.prevent

.prevent 事件修饰符只是阻止默认事件&#xff0c;不会自动触发任何事件处理函数。因此&#xff0c;在使用 .prevent 事件修饰符时&#xff0c;需要自己编写相应的事件处理函数来处理事件。 例如&#xff0c;在上面的例子中&#xff0c;我们通过在表单上绑定 submit.prevent&q…...

【SpringCloud AlibabaSentinel实现熔断与限流】

本笔记内容为尚硅谷SpringCloud AlibabaSentinel部分 目录 一、Sentinel 1、官网 2、Sentinel是什么 3、下载 4、特性 5、使用 二、安装Sentinel控制台 1、sentinel组件由2部分构成 2、安装步骤 1.下载 2.运行命令 3.访问sentinel管理界面 三、初始化演示工程 …...

类与对象-封装

一、封装的意义封装是C面向对象三大特性之一语法&#xff1a; class name { 访问权限:属性行为 };注意&#xff1a;类中的属性和行为 统称为成员属性 又称 成员属性 / 成员变量行为 又称 成员函数 / 成员方法封装将属性和行为作为一个整体&#xff0c;表现生活中的事物例①&…...

【回忆杀】2012年拥有第一台电脑【致逝去的青春】

高中说起 在2012年的时候吧&#xff0c;高考过后&#xff0c;那个时候一门心思的想当一名体育老师【现在居然还有这个想法&#xff0c;哈哈】&#xff0c;最后没有考上自己希望的大学我记得好像是2012年7月的时候就去重庆投靠朋友&#xff0c;他教我做模具&#xff0c;2012年做…...

PointNeXt: Revisiting PointNet++ with Improved Training and Scaling Strategies

Abstract PointNet 是点云理解领域最有影响力的神经网络架构之一。虽然近期出现了 PointMLP 和 Point Transformer 等新型网络&#xff0c;它们的精度已经大大超过了 PointNet&#xff0c;但我们发现大部分性能提升是由于改进的训练策略&#xff0c;例如数据增强和优化技术以及…...

打印九九乘法表-课后程序(JavaScript前端开发案例教程-黑马程序员编著-第2章-课后作业)

【案例2-9】打印九九乘法表 一、案例描述 考核知识点 for双重循环 练习目标 掌握for循环应用。实现九九乘法表。 需求分析 九九乘法表相信大家一点也不陌生&#xff0c;之前见到的乘法表是印刷在课程本之上的。而在本案例中我们将用JavaScript代码来实现九九乘法表。 案例分…...

【Linux】基于阻塞队列的生产者消费者模型

​&#x1f320; 作者&#xff1a;阿亮joy. &#x1f386;专栏&#xff1a;《学会Linux》 &#x1f387; 座右铭&#xff1a;每个优秀的人都有一段沉默的时光&#xff0c;那段时光是付出了很多努力却得不到结果的日子&#xff0c;我们把它叫做扎根 目录&#x1f449;为何要使用…...

【华为OD机试 2023最新 】 真正的密码(C++)

文章目录 题目描述输入描述输出描述用例题目解析C++题目描述 在一行中输入一个字符串数组,如果其中一个字符串的所有以索引0开头的子串在数组中都有,那么这个字符串就是潜在密码, 在所有潜在密码中最长的是真正的密码,如果有多个长度相同的真正的密码,那么取字典序最大的…...

差分算法(蓝桥杯复习+例题讲解+模板c++)

文章目录差分介绍差分应用区间加区间求和总结3729. 改变数组元素100. 增减序列文章首发于&#xff1a;My Blog 欢迎大佬们前来逛逛 差分介绍 差分是一种常见的算法&#xff0c;用于快速修改数组中某一段区间的值。 差分的思想就是预处理出数组的差分数组&#xff0c;然后修改…...

CSS+ JS 实现手电筒效果

前言概述 JavaScript 结合 CSS 打造的一款图片特效&#xff0c;当鼠标拖拽滑块时&#xff0c;让本该置灰的图片局部恢复本来的颜色。且该效果随着你的鼠标的按下时的移动而移动。 核心功能 图片置灰 拖拽功能 让滑块位置处的图片恢复本来的颜色 实现原理 这个的实现原理并不…...

2021地理设计组二等奖:基于InSAR和指数分析的地面沉降风

作品简介 一、作品背景 地面沉降是指地面高程的降低, 又称地面下沉或地沉, 是以缓慢、难以察觉的向下垂直运动为主, 是指在自然和人为因素作用下, 由于地壳表层土体压缩而导致区域性地面标高降低的一种环境现象。目前, 地面沉降己成为城市化进程中普遍存在的生态环境问题, 成为…...

计算机操作系统(第四版)第二章进程的描述与控制—课后习题答案

1.什么是前趋图&#xff1f;为什么要引入前趋图&#xff1f; 前趋图是一个有向无循环图&#xff0c;记为DAG&#xff0c;用于描述进程之间执行的先后关系。 2.试画出下面四条语句的前趋图&#xff1a; S1:axy; S2:bz1; S3:ca-b; S4:wc1; 3.为什么程序并发执行会产生间断性特征&…...

CAN通信----电路图

CAN通信----基本原理 一、CAN总线网络连接 1.闭环总线网络----ISO11898 闭环总线网络高速、短距离&#xff0c;它的总线最大长度为 40m&#xff0c;通信速度最高为 1Mbps&#xff0c;总线的两端各要求有一个120 欧的电阻。 2.开环总线网络----ISO11519 开环总线网络低速、…...

Windows系统安装ElasticSearch(一)

一 ES介绍Elasticsearch 是一个分布式可扩展的实时搜索和分析引擎,一个建立在全文搜索引擎 Apache Lucene(TM) 基础上的搜索引擎.当然 Elasticsearch 并不仅仅是 Lucene 那么简单&#xff0c;它不仅包括了全文搜索功能&#xff0c;还可以进行以下工作:分布式实时文件存储&#…...

linux 产生随机数 并遍历

1、产生随机数 varRANDOMvarRANDOM varRANDOMvar[ $var % 150 ] 2、产生不重复的随机数 $ entries($(shuf -i 0-149 -n 15)) $ echo “${entries[]}” 3、对随机数排序 $ entries($(shuf -i 0-149 -n 15 | sort -n)) $ echo “entries[]"12224549546678798393118119124140…...

【3.24】Mybatis常见面试题

Mybatis常见面试题 #{}和&#xffe5;{}的区别是什么&#xff1f; 【#】&#xff1a;底层执行SQL使用PreparedStatement对象&#xff0c;预编译SQL&#xff0c;相对安全。入参使用占位符的方式。 【$】&#xff1a;底层执行SQL使用Statement对象&#xff0c;入参使用SQL拼接的…...

IDEA 热部署,修改代码不用重启项目

热部署指在修改项目代码的时候不重启服务器让修改生效。安装JRebel and XRebelFile->Settings&#xff0c;然后Plugins-> Marketplace&#xff0c;输入JRebel&#xff0c;安装如下插件——JRebel and XRebel &#xff0c;重启idea激活JRebel and XRebel第一行输入网址&am…...

[ICLR 2022]How Much Can CLIP Benefit Vision-and-Language Tasks?

论文网址&#xff1a;pdf 英文是纯手打的&#xff01;论文原文的summarizing and paraphrasing。可能会出现难以避免的拼写错误和语法错误&#xff0c;若有发现欢迎评论指正&#xff01;文章偏向于笔记&#xff0c;谨慎食用 目录 1. 心得 2. 论文逐段精读 2.1. Abstract 2…...

质量体系的重要

质量体系是为确保产品、服务或过程质量满足规定要求&#xff0c;由相互关联的要素构成的有机整体。其核心内容可归纳为以下五个方面&#xff1a; &#x1f3db;️ 一、组织架构与职责 质量体系明确组织内各部门、岗位的职责与权限&#xff0c;形成层级清晰的管理网络&#xf…...

Python Einops库:深度学习中的张量操作革命

Einops&#xff08;爱因斯坦操作库&#xff09;就像给张量操作戴上了一副"语义眼镜"——让你用人类能理解的方式告诉计算机如何操作多维数组。这个基于爱因斯坦求和约定的库&#xff0c;用类似自然语言的表达式替代了晦涩的API调用&#xff0c;彻底改变了深度学习工程…...

安卓基础(Java 和 Gradle 版本)

1. 设置项目的 JDK 版本 方法1&#xff1a;通过 Project Structure File → Project Structure... (或按 CtrlAltShiftS) 左侧选择 SDK Location 在 Gradle Settings 部分&#xff0c;设置 Gradle JDK 方法2&#xff1a;通过 Settings File → Settings... (或 CtrlAltS)…...

QT开发技术【ffmpeg + QAudioOutput】音乐播放器

一、 介绍 使用ffmpeg 4.2.2 在数字化浪潮席卷全球的当下&#xff0c;音视频内容犹如璀璨繁星&#xff0c;点亮了人们的生活与工作。从短视频平台上令人捧腹的搞笑视频&#xff0c;到在线课堂中知识渊博的专家授课&#xff0c;再到影视平台上扣人心弦的高清大片&#xff0c;音…...

归并排序:分治思想的高效排序

目录 基本原理 流程图解 实现方法 递归实现 非递归实现 演示过程 时间复杂度 基本原理 归并排序(Merge Sort)是一种基于分治思想的排序算法&#xff0c;由约翰冯诺伊曼在1945年提出。其核心思想包括&#xff1a; 分割(Divide)&#xff1a;将待排序数组递归地分成两个子…...

数据结构:泰勒展开式:霍纳法则(Horner‘s Rule)

目录 &#x1f50d; 若用递归计算每一项&#xff0c;会发生什么&#xff1f; Horners Rule&#xff08;霍纳法则&#xff09; 第一步&#xff1a;我们从最原始的泰勒公式出发 第二步&#xff1a;从形式上重新观察展开式 &#x1f31f; 第三步&#xff1a;引出霍纳法则&…...

CTF show 数学不及格

拿到题目先查一下壳&#xff0c;看一下信息 发现是一个ELF文件&#xff0c;64位的 ​ 用IDA Pro 64 打开这个文件 ​ 然后点击F5进行伪代码转换 可以看到有五个if判断&#xff0c;第一个argc ! 5这个判断并没有起太大作用&#xff0c;主要是下面四个if判断 ​ 根据题目…...

Redis上篇--知识点总结

Redis上篇–解析 本文大部分知识整理自网上&#xff0c;在正文结束后都会附上参考地址。如果想要深入或者详细学习可以通过文末链接跳转学习。 1. 基本介绍 Redis 是一个开源的、高性能的 内存键值数据库&#xff0c;Redis 的键值对中的 key 就是字符串对象&#xff0c;而 val…...

二叉树-144.二叉树的前序遍历-力扣(LeetCode)

一、题目解析 对于递归方法的前序遍历十分简单&#xff0c;但对于一位合格的程序猿而言&#xff0c;需要掌握将递归转化为非递归的能力&#xff0c;毕竟递归调用的时候会调用大量的栈帧&#xff0c;存在栈溢出风险。 二、算法原理 递归调用本质是系统建立栈帧&#xff0c;而非…...