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_struct和struct 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.你真的理解文件原理和操作了吗?不是语言问题,是系统问题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 的使用方法并在其基…...
树莓派学习笔记(十三)基于框架编写驱动代码
文章目录一、代码分析:二、源码一、代码分析: 在内核中由于代码文件多,避免函数名重复,使用static将函数的作用域限制在该文件内 内核的打印函数printk和printf类似 file_operations结构体使用符号“ . ”指定参数,省…...
vue事件修饰符之.prevent
.prevent 事件修饰符只是阻止默认事件,不会自动触发任何事件处理函数。因此,在使用 .prevent 事件修饰符时,需要自己编写相应的事件处理函数来处理事件。 例如,在上面的例子中,我们通过在表单上绑定 submit.prevent&q…...
【SpringCloud AlibabaSentinel实现熔断与限流】
本笔记内容为尚硅谷SpringCloud AlibabaSentinel部分 目录 一、Sentinel 1、官网 2、Sentinel是什么 3、下载 4、特性 5、使用 二、安装Sentinel控制台 1、sentinel组件由2部分构成 2、安装步骤 1.下载 2.运行命令 3.访问sentinel管理界面 三、初始化演示工程 …...
类与对象-封装
一、封装的意义封装是C面向对象三大特性之一语法: class name { 访问权限:属性行为 };注意:类中的属性和行为 统称为成员属性 又称 成员属性 / 成员变量行为 又称 成员函数 / 成员方法封装将属性和行为作为一个整体,表现生活中的事物例①&…...
【回忆杀】2012年拥有第一台电脑【致逝去的青春】
高中说起 在2012年的时候吧,高考过后,那个时候一门心思的想当一名体育老师【现在居然还有这个想法,哈哈】,最后没有考上自己希望的大学我记得好像是2012年7月的时候就去重庆投靠朋友,他教我做模具,2012年做…...
PointNeXt: Revisiting PointNet++ with Improved Training and Scaling Strategies
Abstract PointNet 是点云理解领域最有影响力的神经网络架构之一。虽然近期出现了 PointMLP 和 Point Transformer 等新型网络,它们的精度已经大大超过了 PointNet,但我们发现大部分性能提升是由于改进的训练策略,例如数据增强和优化技术以及…...
打印九九乘法表-课后程序(JavaScript前端开发案例教程-黑马程序员编著-第2章-课后作业)
【案例2-9】打印九九乘法表 一、案例描述 考核知识点 for双重循环 练习目标 掌握for循环应用。实现九九乘法表。 需求分析 九九乘法表相信大家一点也不陌生,之前见到的乘法表是印刷在课程本之上的。而在本案例中我们将用JavaScript代码来实现九九乘法表。 案例分…...
【Linux】基于阻塞队列的生产者消费者模型
🌠 作者:阿亮joy. 🎆专栏:《学会Linux》 🎇 座右铭:每个优秀的人都有一段沉默的时光,那段时光是付出了很多努力却得不到结果的日子,我们把它叫做扎根 目录👉为何要使用…...
【华为OD机试 2023最新 】 真正的密码(C++)
文章目录 题目描述输入描述输出描述用例题目解析C++题目描述 在一行中输入一个字符串数组,如果其中一个字符串的所有以索引0开头的子串在数组中都有,那么这个字符串就是潜在密码, 在所有潜在密码中最长的是真正的密码,如果有多个长度相同的真正的密码,那么取字典序最大的…...
差分算法(蓝桥杯复习+例题讲解+模板c++)
文章目录差分介绍差分应用区间加区间求和总结3729. 改变数组元素100. 增减序列文章首发于:My Blog 欢迎大佬们前来逛逛 差分介绍 差分是一种常见的算法,用于快速修改数组中某一段区间的值。 差分的思想就是预处理出数组的差分数组,然后修改…...
CSS+ JS 实现手电筒效果
前言概述 JavaScript 结合 CSS 打造的一款图片特效,当鼠标拖拽滑块时,让本该置灰的图片局部恢复本来的颜色。且该效果随着你的鼠标的按下时的移动而移动。 核心功能 图片置灰 拖拽功能 让滑块位置处的图片恢复本来的颜色 实现原理 这个的实现原理并不…...
2021地理设计组二等奖:基于InSAR和指数分析的地面沉降风
作品简介 一、作品背景 地面沉降是指地面高程的降低, 又称地面下沉或地沉, 是以缓慢、难以察觉的向下垂直运动为主, 是指在自然和人为因素作用下, 由于地壳表层土体压缩而导致区域性地面标高降低的一种环境现象。目前, 地面沉降己成为城市化进程中普遍存在的生态环境问题, 成为…...
计算机操作系统(第四版)第二章进程的描述与控制—课后习题答案
1.什么是前趋图?为什么要引入前趋图? 前趋图是一个有向无循环图,记为DAG,用于描述进程之间执行的先后关系。 2.试画出下面四条语句的前趋图: S1:axy; S2:bz1; S3:ca-b; S4:wc1; 3.为什么程序并发执行会产生间断性特征&…...
CAN通信----电路图
CAN通信----基本原理 一、CAN总线网络连接 1.闭环总线网络----ISO11898 闭环总线网络高速、短距离,它的总线最大长度为 40m,通信速度最高为 1Mbps,总线的两端各要求有一个120 欧的电阻。 2.开环总线网络----ISO11519 开环总线网络低速、…...
Windows系统安装ElasticSearch(一)
一 ES介绍Elasticsearch 是一个分布式可扩展的实时搜索和分析引擎,一个建立在全文搜索引擎 Apache Lucene(TM) 基础上的搜索引擎.当然 Elasticsearch 并不仅仅是 Lucene 那么简单,它不仅包括了全文搜索功能,还可以进行以下工作:分布式实时文件存储&#…...
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常见面试题 #{}和¥{}的区别是什么? 【#】:底层执行SQL使用PreparedStatement对象,预编译SQL,相对安全。入参使用占位符的方式。 【$】:底层执行SQL使用Statement对象,入参使用SQL拼接的…...
IDEA 热部署,修改代码不用重启项目
热部署指在修改项目代码的时候不重启服务器让修改生效。安装JRebel and XRebelFile->Settings,然后Plugins-> Marketplace,输入JRebel,安装如下插件——JRebel and XRebel ,重启idea激活JRebel and XRebel第一行输入网址&am…...
重新定义AI助手体验:突破Cursor Pro限制的5个技术方案
重新定义AI助手体验:突破Cursor Pro限制的5个技术方案 【免费下载链接】cursor-free-vip [Support 0.45](Multi Language 多语言)自动注册 Cursor Ai ,自动重置机器ID , 免费升级使用Pro 功能: Youve reached your tri…...
Clawdbot整合Qwen3:32B效果体验:长文档理解与精准问答演示
Clawdbot整合Qwen3:32B效果体验:长文档理解与精准问答演示 1. 从痛点出发:为什么你需要这个工具 如果你经常需要处理技术文档、合同、论文或者产品手册,一定遇到过这样的困扰:面对一份几十页甚至上百页的PDF文件,想要…...
DanKoe 视频笔记:人生经验课:给18岁自己的信
在本节课中,我们将学习一位28岁人士回顾过去,总结出的核心人生经验。这些经验旨在帮助年轻人,特别是那些感到迷茫、渴望超越平凡生活的人,建立自主性、明确目标并采取有效行动。我们将把这些经验整理成一套清晰的教程,…...
从零开始理解JVM内存模型:如何避免OOM错误的7个实用技巧
从零开始理解JVM内存模型:如何避免OOM错误的7个实用技巧 第一次在线上环境遇到OOM错误时,我盯着控制台那行刺眼的java.lang.OutOfMemoryError整整愣了三分钟。那是一个看似普通的周二下午,我们的订单处理系统突然开始拒绝服务,而监…...
别再花冤枉钱!和腰突颈椎病斗了 3 年,我终于踩中了康复的捷径
有没有和我一样的打工人,每天久坐 8 小时起步,下班就低头刷手机,年纪轻轻颈椎腰椎先 “垮了”? 从最开始的脖子发酸、腰部发僵,到后来疼到睡不着觉、手麻到握不住鼠标,甚至走路都直不起腰,这 3…...
从羊肠小道到智能高速:HTTP1到HTTP3的演进之路
引言 计算机网络就像一张遍布全球的道路系统,服务器是一座座城市、村庄,客户端是穿梭其中的车辆,而HTTP协议,就是规范车辆通行、货物传递的交通规则。从HTTP1到HTTP3的演进,本质上就是这条“网络道路”的升级史——从泥…...
Qwen3-8B快速体验报告:部署简单,中文理解能力确实强
Qwen3-8B快速体验报告:部署简单,中文理解能力确实强 1. 开箱即用的AI体验 最近在测试各种开源大模型时,我发现了Qwen3-8B这个宝藏模型。作为Qwen系列的最新成员,这个80亿参数的模型在中文理解和推理能力上表现突出,最…...
C++ 中this的秘密
class Test {public:void test() {test1();}void test1() {i = 10...
3分钟搞定跨平台:Whisky让你的Mac运行Windows应用零障碍
3分钟搞定跨平台:Whisky让你的Mac运行Windows应用零障碍 【免费下载链接】Whisky A modern Wine wrapper for macOS built with SwiftUI 项目地址: https://gitcode.com/gh_mirrors/wh/Whisky 你是否曾经在Mac上需要运行某个Windows专属软件而感到束手无策&a…...
Zigbee网关配网操作全解析:从连接到触发
1. Zigbee网关配网前的准备工作 第一次接触Zigbee网关配网的朋友可能会觉得有点复杂,但其实只要跟着步骤一步步来,整个过程并不难。我刚开始接触时也踩过不少坑,现在把这些经验都整理出来,希望能帮你少走弯路。 首先得确认你的硬件…...
