【Linux系统编程】第二十六弹---彻底掌握文件I/O:C/C++文件接口与Linux系统调用实践
✨个人主页: 熬夜学编程的小林
💗系列专栏: 【C语言详解】 【数据结构详解】【C++详解】【Linux系统编程】
目录
1、回顾C语言文件接口
1.1、以写的方式打开文件
1.2、以追加的方式打开文件
2、初步理解文件
2.1、C++文件接口
3、进一步理解文件
3.1、系统调用实现写方式打开文件
3.2、系统调用实现追加打开文件
3.3、理解open第二个参数原理
1、回顾C语言文件接口
1.1、以写的方式打开文件
1、如果文件不存在,就在当前路径下新建指定的文件。
2、默认打开文件的时候,会先清空文件 -> 等价于 >输出重定向。
代码演示一
#include<stdio.h>int main()
{// 以写方式打开文件FILE* fd = fopen("log.txt","w");if(fd == NULL) {perror("fopen");return 1;}// 向文件写内容fprintf(fd,"helloworld,%d,%s,%lf\n",10,"abcd",3.14);// 关闭文件fclose(fd);return 0;
}
运行结果

代码演示二
#include<stdio.h>int main()
{// 以写方式打开文件FILE* fd = fopen("log.txt","w");if(fd == NULL) {perror("fopen");return 1;}fclose(fd);return 0;
}
运行结果

看一段命令
[jkl@host file]$ cat log.txt
helloworld,10,abcd,3.140000
[jkl@host file]$ echo "hello linux" > log.txt
[jkl@host file]$ cat log.txt
hello linux
[jkl@host file]$ > file.txt
[jkl@host file]$ ls
file.txt log.txt makefile myfile myfile.c
[jkl@host file]$ cat log.txt
hello linux
[jkl@host file]$ >log.txt
[jkl@host file]$ cat log.txt
[jkl@host file]$
解析命令

结论:
重定向 > 可以创建新文件和清空文件内容。
1.2、以追加的方式打开文件
1、如果文件不存在,就在当前路径下新建指定的文件。
2、默认打开文件的时候,会在末尾追加内容 -> 等价于 >>输出重定向。
代码演示
#include<stdio.h>int main()
{// 以追加的方式打开文件FILE* fd = fopen("log.txt","a");if(fd == NULL) {perror("fopen");return 1;}fprintf(fd,"helloworld,%d,%s,%lf\n",10,"abcd",3.14);fclose(fd);return 0;
}
运行结果

看一段命令
[jkl@host file]$ ./myfile
[jkl@host file]$ cat log.txt
helloworld,10,abcd,3.140000
helloworld,10,abcd,3.140000
helloworld,10,abcd,3.140000
[jkl@host file]$ cat myfile.c
[jkl@host file]$ echo "hello linux" >> log.txt
[jkl@host file]$ cat log.txt
helloworld,10,abcd,3.140000
helloworld,10,abcd,3.140000
helloworld,10,abcd,3.140000
hello linux
[jkl@host file]$ >> file1.txt
[jkl@host file]$ ls
file1.txt file.txt log.txt makefile myfile myfile.c
解析命令

结论:
>> 追加重定向可以创建新文件和追加文件内容。
2、初步理解文件
- 文件 = 属性 + 内容
- 打开文件:本质是进程(struct task_struct)打开文件(struct xxx)
- 文件没有打开的时候,存放在哪里?硬盘。
- 进程能打开很多文件吗?可以
- 系统能否存在很多进程?可以
- 很多情况下,OS内部存在大量被打开的文件 -> OS是否要将被打开的文件进行管理 -> 怎么管理呢?先描述在组织 -> 预言:每一个被打开的文件,在OS内部,一定要存在对应的描述文件属性的结构体,类似于PCB。
2.1、C++文件接口
以写的方式打开文件。
代码演示
#include<iostream>
#include<fstream>
#include<string>#define FILENAME "log.txt"int main()
{// out写方式 in读方式 app追加 binary二进制std::ofstream out(FILENAME,std::ios_base::out);// is_open() 检查文件是否打开if(!out.is_open()) return 1; //打开失败,结束程序std::string msg = "hello C++!\n";// ostream& write (const char* s, streamsize n);out.write(msg.c_str(),msg.size());// 关闭文件out.close();return 0;
}
运行结果

3、进一步理解文件
操作文件:本质是进程在操作文件,即进程与文件的关系。
文件 ->存储在硬盘中 -> 硬盘是一个外设 -> 外设是一个硬件 -> 向文件中写入本质是向硬件中写入 -> 用户没有权利直接写入 -> OS是硬件的管理者 -> 通过OS写入 -> OS必须给我们提供系统调用(因为OS不相信任何人) -> fopen/fwrite/fread/fclose ... -> 我们用的都是C/C++/... 对系统调用接口的封装! -> 访问文件,我们也可以直接使用系统调用!!!
为什么要对系统调用的接口进行封装?怎么封装?
后序回答。
使用系统调用接口来操作文件!!!
系统调用接口函数
打开文件
#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);pathname: 要打开或创建的目标文件。
flags: 打开文件时,可以传入多个参数选项,用下面的一个或者多个常量进行“或”运算,构成flags。
mode:设置默认权限信息。
参数:O_RDONLY: 只读打开O_WRONLY: 只写打开O_RDWR : 读,写打开这三个常量,必须指定一个且只能指定一个O_CREAT : 若文件不存在,则创建它。需要使用mode选项,来指明新文件的访问权限O_APPEND: 追加写O_TRUNC : 若文件存在会先清空文件
返回值:成功:新打开的文件描述符失败:-1
向文件中写内容
#include <unistd.h>
ssize_t write(int fd, const void *buf, size_t count);
将缓冲区指向的 buf 内容中的count个字节数写入到文件描述符 fd 引用的文件。
关闭文件
#include <unistd.h>
int close(int fd);
关闭文件描述符 fd 引用的文件。
3.1、系统调用实现写方式打开文件
系统调用可能用到的头文件
#include<stdio.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<string.h>
#include<unistd.h>
代码演示一(不设置权限信息)
int main()
{int fd = open("log.txt",O_WRONLY | O_CREAT | O_TRUNC);if(fd < 0){perror("open");return 1;}// ssize_t write(int fd, const void *buf, size_t count);const char* msg = "hello linux file!\n";write(fd,msg,strlen(msg));close(fd);return 0;
}
运行结果

上面的代码演示的是文件不存在,在当前路径创建指定文件,但没有设置默认权限的情况。
代码演示一(只设置权限信息)
int main()
{int fd = open("log.txt",O_WRONLY | O_CREAT | O_TRUNC,0666);if(fd < 0){perror("open");return 1;}// ssize_t write(int fd, const void *buf, size_t count);const char* msg = "hello linux file!\n";write(fd,msg,strlen(msg));close(fd);return 0;
}
运行结果

上面的代码演示的是文件不存在,在当前路径创建指定文件,且设置默认权限的情况。
想要第三个参数是什么权限文件就是什么权限应该怎么办呢???
将umask值设置为0即可。
#include <sys/types.h>
#include <sys/stat.h>mode_t umask(mode_t mask);
设置umask值。
代码演示三(设置权限信息和umask)
int main()
{umask(0);int fd = open("log.txt",O_WRONLY | O_CREAT | O_TRUNC,0666);if(fd < 0){perror("open");return 1;}// ssize_t write(int fd, const void *buf, size_t count);const char* msg = "hello linux file!\n";write(fd,msg,strlen(msg));close(fd);return 0;
}
运行结果

上面的代码演示的是文件不存在,在当前路径创建指定文件,且设置默认权限和umask的情况。
代码演示四
int main()
{umask(0);int fd = open("log.txt",O_WRONLY | O_CREAT | O_TRUNC,0777);if(fd < 0){perror("open");return 1;}close(fd);return 0;
}
运行结果

上面的代码演示的是文件存在,先清空文件内容,即使修改默认权限,也不会影响该文件的权限。
3.2、系统调用实现追加打开文件
代码演示
int main()
{umask(0);int fd = open("log.txt",O_WRONLY | O_CREAT | O_APPEND,0666);if(fd < 0){perror("open");return 1;}// ssize_t write(int fd, const void *buf, size_t count);const char* msg = "hello linux file!\n";write(fd,msg,strlen(msg));close(fd);return 0;
}
运行结果

3.3、理解open第二个参数原理
原理是位图加位运算,下面通过一个程序理解调用open第二个参数原理。
代码演示
#define ONE 1 // 0000 0001
#define TWO (1<<1) // 0000 0010
#define THREE (1<<2) // 0000 0100
#define FOUR (1<<3) // 0000 1000void print(int flag)
{if(flag & ONE){printf("one\n");}if(flag & TWO){printf("two\n");}if(flag & THREE){printf("three\n");}if(flag & FOUR){printf("four\n");}
}
int main()
{print(ONE);printf("\n");print(TWO);printf("\n");print(ONE | TWO);printf("\n");print(ONE | TWO | THREE);printf("\n");print(ONE | TWO | THREE | FOUR);printf("\n");return 0;
}
运行结果

相关文章:
【Linux系统编程】第二十六弹---彻底掌握文件I/O:C/C++文件接口与Linux系统调用实践
✨个人主页: 熬夜学编程的小林 💗系列专栏: 【C语言详解】 【数据结构详解】【C详解】【Linux系统编程】 目录 1、回顾C语言文件接口 1.1、以写的方式打开文件 1.2、以追加的方式打开文件 2、初步理解文件 2.1、C文件接口 3、进一步理…...
数据分析-29-基于pandas的窗口操作和对JSON格式数据的处理
文章目录 1 窗口操作1.1 滑动窗口思想1.2 函数df.rolling2 JSON格式数据2.1 处理简单JSON对象和JSON列表2.1.1 处理简单的JSON结构2.1.2 处理空字段2.1.3 获取部分字段2.2 处理多级json2.2.1 展开所有级别(默认)2.2.2 自定义展开层级2.3 处理嵌套列表JSON3 参考附录1 窗口操作 …...
Ubuntu-WSL2一键设置代理操作
现状: Window11中拥有自己的代理软件 ,可以科学上网已在WSL2中安装Ubuntu22.04 需求: Ubuntu-WSL2实现科学上网 实现: 参考:为 WSL2 一键设置代理 Linux 子系统中的网关指向的是 Windows,DNS 服务器指…...
ubuntu命令行连接wifi
在Ubuntu上,你可以通过命令行连接到Wi-Fi网络。以下是详细步骤,主要使用 nmcli 和 nmtui 命令。 方法 1:使用 nmcli nmcli 是 NetworkManager 的命令行界面,用于管理网络连接。以下是使用 nmcli 连接到 Wi-Fi 网络的步骤&#x…...
日常工作第10天:
vim 批量编辑的命令是 移动光标到列首。按键 CtrlV 进入 Visual block 模式,标记你想要进行编辑的列(HJKL可以向左下上右移动光标)。按键 ShiftI 进入 Insert 模式,在列首输入文本;或者 Shift A,追加文本…...
CNN+Transformer解说
CNN(卷积神经网络)和Transformer是两种在深度学习领域广泛使用的模型架构,它们在处理不同类型的数据和任务时各有优势。 CNN擅长捕捉局部特征和空间层次结构,而Transformer擅长处理序列数据和长距离依赖关系。 将CNN与Transform…...
jmeter中token测试
案例: 网站:http://shop.duoceshi.com 讲解:用三个接口来讲解 第一个接口code:GET http://manage.duoceshi.com/auth/code 第二个登录接口:http://manage.duoceshi.com/auth/login 第三个接口:http://…...
基于解压缩模块的JPEG同步重压缩检测论文学习
一、论文基本信息: 论文题目:基于解压缩模块的JPEG同步重压缩检测 作者:王金伟1 ,胡冰涛1 ,张家伟1 ,马 宾2 ,罗向阳3 (1.南京信息工程大学计算机学院、网络空间安全学院…...
音视频入门基础:FLV专题(7)——Tag header简介
一、引言 从《音视频入门基础:FLV专题(3)——FLV header简介》中可以知道, 在FLV header之后,FLV文件剩下的部分应由PreviousTagSize和Tag组成。FLV文件 FLV header PreviousTagSize0 Tag1 PreviousTagSize1 Ta…...
【Linux 报错】“make: ‘xxxx‘ is up to date.” 解决办法
一、报错原因 我们使用 make 命令,想要将 text.c 文件编译形成 可执行文件 text 时,报错如下 make: test is up to date. 中文含义:test 文件已经达到最新状态 意思是: test.c 文件里面的 所有源代码都没有修改过,你…...
【FPGA开发】Xilinx FPGA差分输入时钟的使用方法
正文 以前在使用ZYNQ的领航者ZYNQ7020进行FPGA学习时,它们使用的单端50M的输入时钟,在verlog代码编写上比较简单,而现在使用Alinx的AXU3EG开发板时,发现它使用的是200M的差分输入时钟,哪这个时候,输入时钟要…...
面试扩展知识点
1.C语言中分为下面几个存储区 栈(stack): 由编译器自动分配释放堆(heap): 一般由程序员分配释放,若程序员不释放,程序结束时可能由OS回收全局区(静态区): 全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块区域&#…...
【经验分享】MyCAT 中间件
学习了一下数据量过大的解决方案,使用 MyCAT 中间件。 MyCAT 可以解决分布式事务、读写分离、主从、分片等一系列MySQL集群和分布式问题。 整体过程可以概括为拦截 - 分发 - 响应 例如设置 MyCAT 分片规则为每500万条数据就换一个数据库存储。 分库分表的中心思想都是将数据…...
Kotlin:1.8.0 的新特性
一、概述 Kotlin 1.8.0版本英语官方文档 Kotlin 1.8.0 中文官方文档 The Kotlin 1.8.0 release is out and here are some of its biggest highlights: Kotlin 1.8.0发布了,下面是它的一些亮点: JVM 平台新增实验性函数:递归复制或删除目录内容改进了 …...
深度学习之开发环境(CUDA、Conda、Pytorch)准备(4)
目录 1.CUDA 介绍 1.1 CUDA 的基本概念 1.2 CUDA 的工作原理 1.3 CUDA 的应用领域 2. 安装CUDA 2.1 查看GPU版本 2.2 升级驱动(可选) 2.3 查看CUDA版本驱动对应的支持的CUDA ToolKit工具包 2.4 下载Toolkit 2.5 安装(省略࿰…...
10月2日笔记(内网资源探测篇)
内网资源探测 在内网渗透中,测试人员往往需要通过各种内网扫描技术来探测内网资源的情况,为后续的横向渗透做准备,通常需要发现内网存活的主机,并探测主机的操作系统、主机开放了哪些端口、端口上运行了哪些服务、服务的当前版本…...
SpringCloud-基于Docker和Docker-Compose的项目部署
一、初始化环境 1. 卸载旧版本 首先,卸载可能已存在的旧版本 Docker。如果您不确定是否安装过,可以直接执行以下命令: sudo yum remove docker \docker-client \docker-client-latest \docker-common \docker-latest \docker-latest-logro…...
Linux下的基本指令/命令(一)
目录 基本命令 1. Is命令/指令: 罗列当前目录下指定的文件或者目录. 2. pwd命令: 查看当前工作的路径 3. cd命令: 切换到指定路径下。 只能切换到目录中 4. tree命令: 树状显式目录 使用前要输入命令 yum install -y tree ,用来安装一个…...
从零开始Ubuntu24.04上Docker构建自动化部署(四)Docker安装gitlab
你会发现所有gitlab都无法拉取到的情况下,经查找极狐下的gitlab还可以下载,具体如下: 建议保存地址: https://packages.gitlab.cn/#browse/searchkeyword%3Dgitlab 最新版本: sudo docker pull registry.gitlab.cn…...
No module named ‘_ssl‘
目录 背景具体报错检验升级过程步骤一:升级ssl。步骤二:重新编译安装python 背景 换了台服务器按照之前centos升级python版本升级python正常编译安装成功,但是当使用时又出现了奇怪的报错,估计是机器太老了 具体报错 这个报错也…...
Vue记事本应用实现教程
文章目录 1. 项目介绍2. 开发环境准备3. 设计应用界面4. 创建Vue实例和数据模型5. 实现记事本功能5.1 添加新记事项5.2 删除记事项5.3 清空所有记事 6. 添加样式7. 功能扩展:显示创建时间8. 功能扩展:记事项搜索9. 完整代码10. Vue知识点解析10.1 数据绑…...
springboot 百货中心供应链管理系统小程序
一、前言 随着我国经济迅速发展,人们对手机的需求越来越大,各种手机软件也都在被广泛应用,但是对于手机进行数据信息管理,对于手机的各种软件也是备受用户的喜爱,百货中心供应链管理系统被用户普遍使用,为方…...
云启出海,智联未来|阿里云网络「企业出海」系列客户沙龙上海站圆满落地
借阿里云中企出海大会的东风,以**「云启出海,智联未来|打造安全可靠的出海云网络引擎」为主题的阿里云企业出海客户沙龙云网络&安全专场于5.28日下午在上海顺利举办,现场吸引了来自携程、小红书、米哈游、哔哩哔哩、波克城市、…...
无法与IP建立连接,未能下载VSCode服务器
如题,在远程连接服务器的时候突然遇到了这个提示。 查阅了一圈,发现是VSCode版本自动更新惹的祸!!! 在VSCode的帮助->关于这里发现前几天VSCode自动更新了,我的版本号变成了1.100.3 才导致了远程连接出…...
Opencv中的addweighted函数
一.addweighted函数作用 addweighted()是OpenCV库中用于图像处理的函数,主要功能是将两个输入图像(尺寸和类型相同)按照指定的权重进行加权叠加(图像融合),并添加一个标量值&#x…...
【python异步多线程】异步多线程爬虫代码示例
claude生成的python多线程、异步代码示例,模拟20个网页的爬取,每个网页假设要0.5-2秒完成。 代码 Python多线程爬虫教程 核心概念 多线程:允许程序同时执行多个任务,提高IO密集型任务(如网络请求)的效率…...
CMake控制VS2022项目文件分组
我们可以通过 CMake 控制源文件的组织结构,使它们在 VS 解决方案资源管理器中以“组”(Filter)的形式进行分类展示。 🎯 目标 通过 CMake 脚本将 .cpp、.h 等源文件分组显示在 Visual Studio 2022 的解决方案资源管理器中。 ✅ 支持的方法汇总(共4种) 方法描述是否推荐…...
AI病理诊断七剑下天山,医疗未来触手可及
一、病理诊断困局:刀尖上的医学艺术 1.1 金标准背后的隐痛 病理诊断被誉为"诊断的诊断",医生需通过显微镜观察组织切片,在细胞迷宫中捕捉癌变信号。某省病理质控报告显示,基层医院误诊率达12%-15%,专家会诊…...
使用LangGraph和LangSmith构建多智能体人工智能系统
现在,通过组合几个较小的子智能体来创建一个强大的人工智能智能体正成为一种趋势。但这也带来了一些挑战,比如减少幻觉、管理对话流程、在测试期间留意智能体的工作方式、允许人工介入以及评估其性能。你需要进行大量的反复试验。 在这篇博客〔原作者&a…...
MySQL JOIN 表过多的优化思路
当 MySQL 查询涉及大量表 JOIN 时,性能会显著下降。以下是优化思路和简易实现方法: 一、核心优化思路 减少 JOIN 数量 数据冗余:添加必要的冗余字段(如订单表直接存储用户名)合并表:将频繁关联的小表合并成…...
