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

【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系统调用实践

✨个人主页&#xff1a; 熬夜学编程的小林 &#x1f497;系列专栏&#xff1a; 【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一键设置代理操作

现状&#xff1a; Window11中拥有自己的代理软件 &#xff0c;可以科学上网已在WSL2中安装Ubuntu22.04 需求&#xff1a; Ubuntu-WSL2实现科学上网 实现&#xff1a; 参考&#xff1a;为 WSL2 一键设置代理 Linux 子系统中的网关指向的是 Windows&#xff0c;DNS 服务器指…...

ubuntu命令行连接wifi

在Ubuntu上&#xff0c;你可以通过命令行连接到Wi-Fi网络。以下是详细步骤&#xff0c;主要使用 nmcli 和 nmtui 命令。 方法 1&#xff1a;使用 nmcli nmcli 是 NetworkManager 的命令行界面&#xff0c;用于管理网络连接。以下是使用 nmcli 连接到 Wi-Fi 网络的步骤&#x…...

日常工作第10天:

vim 批量编辑的命令是 移动光标到列首。按键 CtrlV 进入 Visual block 模式&#xff0c;标记你想要进行编辑的列&#xff08;HJKL可以向左下上右移动光标&#xff09;。按键 ShiftI 进入 Insert 模式&#xff0c;在列首输入文本&#xff1b;或者 Shift A&#xff0c;追加文本…...

CNN+Transformer解说

CNN&#xff08;卷积神经网络&#xff09;和Transformer是两种在深度学习领域广泛使用的模型架构&#xff0c;它们在处理不同类型的数据和任务时各有优势。 CNN擅长捕捉局部特征和空间层次结构&#xff0c;而Transformer擅长处理序列数据和长距离依赖关系。 将CNN与Transform…...

jmeter中token测试

案例&#xff1a; 网站&#xff1a;http://shop.duoceshi.com 讲解&#xff1a;用三个接口来讲解 第一个接口code&#xff1a;GET http://manage.duoceshi.com/auth/code 第二个登录接口&#xff1a;http://manage.duoceshi.com/auth/login 第三个接口&#xff1a;http://…...

基于解压缩模块的JPEG同步重压缩检测论文学习

一、论文基本信息&#xff1a; 论文题目&#xff1a;基于解压缩模块的JPEG同步重压缩检测 作者&#xff1a;王金伟1 &#xff0c;胡冰涛1 &#xff0c;张家伟1 &#xff0c;马 宾2 &#xff0c;罗向阳3 &#xff08;1.南京信息工程大学计算机学院、网络空间安全学院&#xf…...

音视频入门基础:FLV专题(7)——Tag header简介

一、引言 从《音视频入门基础&#xff1a;FLV专题&#xff08;3&#xff09;——FLV header简介》中可以知道&#xff0c; 在FLV header之后&#xff0c;FLV文件剩下的部分应由PreviousTagSize和Tag组成。FLV文件 FLV header PreviousTagSize0 Tag1 PreviousTagSize1 Ta…...

【Linux 报错】“make: ‘xxxx‘ is up to date.” 解决办法

一、报错原因 我们使用 make 命令&#xff0c;想要将 text.c 文件编译形成 可执行文件 text 时&#xff0c;报错如下 make: test is up to date. 中文含义&#xff1a;test 文件已经达到最新状态 意思是&#xff1a; test.c 文件里面的 所有源代码都没有修改过&#xff0c;你…...

【FPGA开发】Xilinx FPGA差分输入时钟的使用方法

正文 以前在使用ZYNQ的领航者ZYNQ7020进行FPGA学习时&#xff0c;它们使用的单端50M的输入时钟&#xff0c;在verlog代码编写上比较简单&#xff0c;而现在使用Alinx的AXU3EG开发板时&#xff0c;发现它使用的是200M的差分输入时钟&#xff0c;哪这个时候&#xff0c;输入时钟要…...

面试扩展知识点

1.C语言中分为下面几个存储区 栈(stack): 由编译器自动分配释放堆(heap): 一般由程序员分配释放&#xff0c;若程序员不释放&#xff0c;程序结束时可能由OS回收全局区(静态区): 全局变量和静态变量的存储是放在一块的&#xff0c;初始化的全局变量和静态变量在一块区域&#…...

【经验分享】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发布了&#xff0c;下面是它的一些亮点: JVM 平台新增实验性函数&#xff1a;递归复制或删除目录内容改进了 …...

深度学习之开发环境(CUDA、Conda、Pytorch)准备(4)

目录 1.CUDA 介绍 1.1 CUDA 的基本概念 1.2 CUDA 的工作原理 1.3 CUDA 的应用领域 2. 安装CUDA 2.1 查看GPU版本 2.2 升级驱动&#xff08;可选&#xff09; 2.3 查看CUDA版本驱动对应的支持的CUDA ToolKit工具包 2.4 下载Toolkit 2.5 安装&#xff08;省略&#xff0…...

10月2日笔记(内网资源探测篇)

内网资源探测 在内网渗透中&#xff0c;测试人员往往需要通过各种内网扫描技术来探测内网资源的情况&#xff0c;为后续的横向渗透做准备&#xff0c;通常需要发现内网存活的主机&#xff0c;并探测主机的操作系统、主机开放了哪些端口、端口上运行了哪些服务、服务的当前版本…...

SpringCloud-基于Docker和Docker-Compose的项目部署

一、初始化环境 1. 卸载旧版本 首先&#xff0c;卸载可能已存在的旧版本 Docker。如果您不确定是否安装过&#xff0c;可以直接执行以下命令&#xff1a; sudo yum remove docker \docker-client \docker-client-latest \docker-common \docker-latest \docker-latest-logro…...

Linux下的基本指令/命令(一)

目录 基本命令 1. Is命令/指令: 罗列当前目录下指定的文件或者目录. 2. pwd命令&#xff1a; 查看当前工作的路径 3. cd命令&#xff1a; 切换到指定路径下。 只能切换到目录中 4. tree命令: 树状显式目录 使用前要输入命令 yum install -y tree &#xff0c;用来安装一个…...

从零开始Ubuntu24.04上Docker构建自动化部署(四)Docker安装gitlab

你会发现所有gitlab都无法拉取到的情况下&#xff0c;经查找极狐下的gitlab还可以下载&#xff0c;具体如下&#xff1a; 建议保存地址&#xff1a; https://packages.gitlab.cn/#browse/searchkeyword%3Dgitlab 最新版本&#xff1a; sudo docker pull registry.gitlab.cn…...

No module named ‘_ssl‘

目录 背景具体报错检验升级过程步骤一&#xff1a;升级ssl。步骤二&#xff1a;重新编译安装python 背景 换了台服务器按照之前centos升级python版本升级python正常编译安装成功&#xff0c;但是当使用时又出现了奇怪的报错&#xff0c;估计是机器太老了 具体报错 这个报错也…...

告别AI人像翻车!MusePublic艺术创作引擎保姆级入门教程

告别AI人像翻车&#xff01;MusePublic艺术创作引擎保姆级入门教程 &#x1f3db; MusePublic 艺术创作引擎是一款专为艺术感时尚人像创作设计的轻量化文本生成图像系统&#xff0c;基于MusePublic专属大模型&#xff0c;采用safetensors安全格式封装&#xff0c;深度优化优雅…...

SEO_资深从业者的高级SEO策略与实战技巧

前言&#xff1a;SEO的进阶之道 在当今互联网时代&#xff0c;搜索引擎优化&#xff08;SEO&#xff09;已经不再是一个简单的任务。对于资深从业者来说&#xff0c;SEO不仅仅是一门技术&#xff0c;更是一门艺术。本文将从多个角度探讨资深从业者的高级SEO策略与实战技巧&…...

零基础掌握Degrees of Lewdity本地化工具:开源项目中文适配方案全攻略

零基础掌握Degrees of Lewdity本地化工具&#xff1a;开源项目中文适配方案全攻略 【免费下载链接】Degrees-of-Lewdity-Chinese-Localization Degrees of Lewdity 游戏的授权中文社区本地化版本 项目地址: https://gitcode.com/gh_mirrors/de/Degrees-of-Lewdity-Chinese-Lo…...

vLLM推理服务搭建指南:从环境配置到模型上线,一步不漏

vLLM推理服务搭建指南&#xff1a;从环境配置到模型上线&#xff0c;一步不漏 1. vLLM框架简介 vLLM是一个专为大型语言模型(LLM)设计的高性能推理和服务库&#xff0c;以其出色的吞吐量和易用性在AI社区广受欢迎。这个最初由加州大学伯克利分校开发的框架&#xff0c;如今已…...

LaTeX参考文献报错全解析:从\citation到\bibdata的避坑指南

LaTeX参考文献报错全解析&#xff1a;从\citation到\bibdata的避坑指南 当你熬夜赶论文时&#xff0c;突然在编译LaTeX文档时看到一串红色报错&#xff1a;"I found no \bibstyle command"、"I found no \bibdata command"、"I found no \citation co…...

从技术到生态:FunASR如何构建开源语音识别新范式

从技术到生态&#xff1a;FunASR如何构建开源语音识别新范式 FunASR是一个端到端语音识别工具包&#xff0c;提供了丰富的预训练模型和便捷的开发工具&#xff0c;帮助开发者快速构建语音识别应用。本文将深入探讨FunASR的技术架构、核心功能、应用场景以及生态系统&#xff0…...

影墨·今颜开源可部署方案:私有化AI影像系统建设白皮书

影墨今颜开源可部署方案&#xff1a;私有化AI影像系统建设白皮书 1. 引言&#xff1a;重新定义AI影像生成标准 在数字影像创作领域&#xff0c;我们经常面临一个困境&#xff1a;AI生成的图片往往带有明显的"塑料感"&#xff0c;缺乏真实照片的温度和质感。影墨今颜…...

智能客服意图识别实战:基于AI辅助开发的架构设计与避坑指南

在智能客服系统中&#xff0c;意图识别是决定对话能否顺畅进行的关键。简单来说&#xff0c;它就像客服的“耳朵”和“大脑”&#xff0c;需要准确听懂用户五花八门的问法&#xff0c;并快速判断出用户到底想干什么——是查询订单、投诉问题&#xff0c;还是咨询产品。然而&…...

OpenWrt 固件扩容官方指南

[OpenWrt Wiki] Expanding root partition and filesystem OpenWrt针对固件扩容有官方指南&#xff0c;但目前很多网络教程仍然停留在老版本&#xff0c;特此记录。 特点&#xff1a; 1、支持 ext4 和 squashfs 固件格式 2、自动识别根分区和文件系统。 3、利用空闲空间扩…...

UVM实战解析:从零构建高效验证环境的五大核心技巧

1. UVM验证环境搭建的核心逻辑 第一次接触UVM验证方法学时&#xff0c;我被它复杂的类库结构吓到了。直到在项目中真正搭建验证环境才发现&#xff0c;UVM的精髓在于分层设计思想。就像组装乐高积木&#xff0c;每个组件都有明确的职责边界。最让我印象深刻的是&#xff0c;一个…...