【Linux】:文件IO

news2024/9/19 10:38:34

目录

1.C文件接口

1.1 当前路径是什么?

1.2 "w"和"a"​编辑

 2.系统文件I/O

2.1 "比特宏"标识符的实现:

2.2 open

1.系统默认创建文件的权限只写

2.设置新建文件的权限 

3. 覆盖写/清空写/追加写

3.访问文件的本质

3.1 文件描述符

3.2 使用文件描述符

3.3 C库中的标准输出输入 

 3.4 文件描述符的分配规则

4.文件重定向 

4.1 dup2 

4.2 追加重定向 

4.3 输入重定向 

5. 模拟shell实现文件重定向功能

6.为什么文件描述符1和2都指向屏幕 

7. 理解“Linux下一切皆文件”


1.C文件接口

1.1 当前路径是什么?

我们之前学习了fopen,当我们用读方式打开一个不存在的文件时,会在当前目录创建所需文件。第一个参数表示文件路径,如果只写一个文件名,没有写路径,默认在当前目录下打开该文件。

如果写了绝对路径或相对路径,就会去对应的路径下打开所需文件。

那么,这里的当前路径,到底是什么意思呢?如果我们只学习了C语言,没有学习操作系统相关的知识,是很难理解的。这里的当前路径,其实是指程序运行后的进程所在的当前工作目录。

如何证明这一点呢?

我们先在当前目录用fopen的"w"创建一个文件,

然后用chdir更改当前目录,

更改当前目录后,在proc目录下查询对应进程标识符的目录,可以看到cwd发生了改变。

1.2 "w"和"a"

w会截短文件的长度为0或创建一个文件。 我们用"w"的方式在当前目录创建文件,每次运行该程序都会覆盖原log.txt的内容,这说明"w"写入文件前会清空文件。就像重定向一样,我们可以利用重定向清空文件,

但我们还有一个问题,strlen("要写入的字符串")要不要加1,要把"\0"写入到文件中吗?

答案是不需要。因为C语言在内存里没办法标定字符串的结束,没有字符串类型,只好用“\0”来标识字符串的结尾,跟文件没有关系,仅仅是C语言的规定,我们把字符串写到文件里,字符串可能被java、python等语言编写的程序或者其他编译器或者文本编辑器读取,文件又没有规定字符串必须用“\0”结尾。所以我们只要把字符串的内容写入文本中,不用写入“\0”。

如果我们要向文件中“追加写”,可以用“a”。

【C语言】:与文件通信-CSDN博客

 2.系统文件I/O

2.1 "比特宏"标识符的实现:

每一个比特位表示不同的功能,用宏来表示不同的比特位,函数体中用if语句判断"标识符&宏"的真假,通过向函数传递单个或多个按位或的宏,从而实现单个或多个不同的功能。

2.2 open

 第一个参数pathname,表示要打开或要新建的文件名或文件名的路径(包括相对路径或绝对路径,不写路径默认是文件名),

第二个参数flags表示访问文件的格式,

O_RDONLY: 只读打开

O_WRONLY: 只写打开

O_RDWR  : 读,写打开这三个常量,必须指定一个且只能指定一个

O_CREAT : 若文件不存在,则创建它。需要使用mode选项,来指明新文件的访问权限

O_TRUNC:在写之前清空文件,将文件内容的长度截断位0

第三个参数表示创建文件的默认权限.

返回值:打开文件的文件描述符。(详情请往下浏览)

举例:

1.系统默认创建文件的权限只写

2.设置新建文件的权限 

我们可以通过umask系统调用,在进程内部设置局部权限掩码,根据"就近原则", 系统的权限掩码就不会起作用.

3. 覆盖写/清空写/追加写

我们通过系统调用write,向进程中打开的文件内写入内容.

覆盖写:不带参数O_APPEND和O_TRUNC

清空写:O_TRUNC

追加写:O_APPEND

其实C语言的库函数中fopen的第二个参数就是对系统调用open的第二个参数的封装,但是fopen返回值是FILE*类型,而open返回的类型是int,这两个类型又有什么联系呢? 

3.访问文件的本质

3.1 文件描述符

文件描述符在形式上是一个非负整数。实际上,它是一个索引值,指向内核为每一个进程所维护的该进程打开文件的记录表。当程序打开一个现有文件或者创建一个新文件时,内核向进程返回一个文件描述符。 

文件描述符 - 维基百科,自由的百科全书 (wikipedia.org)

文件描述符(file descriptor)就是内核为了高效管理这些已经被打开的文件所创建的索引,其是一个非负整数(通常是小整数),用于指代被打开的文件.

彻底弄懂 Linux 下的文件描述符(fd)_linux fd管理-CSDN博客

一个进程可以打开多个文件,一个文件可以被多个进程打开,这会不会造成冲突呢?

前一个场景我们通过文件描述表使一个进程管理多个文件,而当一个文件被多个进程打开时,在file结构中会有一个成员变量count(可能是别的变量名),专门统计打开该文件的进程数.

如果一个进程proc1打开file,file中的count会加1,另一个进程proc2打开file,count再加1,以此类推.同理,如果进程proc1要关闭file,只要将自己的文件描叙符表中对应的元素(是一个文件指针)置空,file中的count减1,如果count减到0,就真正关闭文件.这其实是采用了"引用计数"的思想.

3.2 使用文件描述符

根据文件描叙符表中的下标,分别向"标准输出"和"标准错误输出"输出字符串.

通过键盘向"标准输入"输入字符串:

3.3 C库中的标准输出输入 

我们知道,C程序运行时,也会默认打开三个标准流,分别是stdin,stdout,stderr .他们的类型都是FILE*,而系统文件I/O,都是通过文件描述符操作文件的,所以FILE必须含有文件描述符.

上面代码中的fileno,就是C库对文件描述符的封装.我们关闭系统的标准输出流1,运行程序,可以发现终端屏幕上什么都没有打印,这是因为我们关闭了系统的标准输出(显示器)接口,而printf打印的字符都是标准输出,我们可以查看一下printf的返回值,

printf返回值是13,说明printf成功读取了13个字符,但由于找不到标准输出流对应的文件描述符,所以无法在屏幕上显示读取成功的字符.

这里有人问,为什么fprintf可以将结果打印到屏幕呢? 因为fprintf是通过标准错误输出流打印到屏幕,关闭的是标准输出流,标准错误输出流并没有关闭.标准输出流和标准错误输出流都是指向屏幕,屏幕被当作一个文件,两个流文件指向同一个硬件,关闭其中一个文件流,是将其文件描述符表中对应下标的文件置空,文件内部的count减1,count减到0,进程才会彻底关闭该硬件(进程无法访问该硬件对应的所有文件).(存疑)

 3.4 文件描述符的分配规则

 从文件描述符表的下标0处开始,寻找最小的未分配下标(这里的未分配意思就是下标对应的元素,也就是文件指针没有指向任何文件,处在未定义或置空状态),给新打开的文件,这个下标就是新打开文件的“文件描述符”。

简而言之,“找小分小”,分配找到的最小未分配下标。

4.文件重定向 

根据文件描述符的分配规则,我们可以将原本要输出到屏幕上的字符串输出到文件log.txt中,这其实就是输出重定向,我们来验证一下,

但这种通过“关闭文件描述符,再打开文件”的方式太繁琐,

4.1 dup2 

我们可以用系统调用dup2,将文件描述符fd1指向的内容拷贝到另一个文件描述符fd2,当我们调用fd2对文件进行操作时,其实是对fd1指向的文件进行操作,

 代码实例:输出重定向原理图:

4.2 追加重定向 

同理,追加重定向我们只要将open的第二个参数中的宏“O_TRUNC”换成"O_APPEND"即可,

4.3 输入重定向 

 还是利用dup2,修改文件描述符指向的内容。

5. 模拟shell实现文件重定向功能

lesson19 · fyehong/Linux_notes - 码云 - 开源中国 (gitee.com)

6.为什么文件描述符1和2都指向屏幕 

在程序运行时,我们在屏幕上可能同时看到程序正常运行时打印的信息以及错误信息,如果把错误信息和正常输出的信息混在一起,用一个文件描述符表示,我们将无法区别错误信息。 不分在一起,我们可以通过重定向,将两种信息输出到两个文件中,互不干扰。

如果我们非要将两种信息输出到同一个文件all.log中, 可以将文件描述符2重定向到1,因为“>all.log”已经将文件描述符1重定向到文件all.log,所以文件描述符1和2都指向文件all.log。

7. 理解“Linux下一切皆文件”

linux文件——重定向原理学习——重定向指令实现、虚拟文件系统_linux文件重定向-CSDN博客

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

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

相关文章

茴香豆Web实践

茴香豆 是由书生浦语团队开发的一款开源、专门针对国内企业级使用场景设计并优化的知识问答工具。 茴香豆特点: 三阶段 Pipeline (前处理、拒答、响应),提高相应准确率和安全性 打通微信和飞书群聊天,适合国内知识问…

提高工作效益方法(一)

目录 如何提高工作效率? 如何提高工作效率?(每日工作安排) 怎么在职场做好时间管理? 如何提高工作效率? 提高工作效率的关键在于采用一系列策略和方法,以确保工作能够高效、有序地进行。通过这些方法,可以有效地提…

【whisper】使用whisper实现语音转文字

whisper需要ffmpeg支持 官网下载ffmpeg https://www.gyan.dev/ffmpeg/builds/下载完毕后解压放到合适的位置 添加环境变量 在cmd中输入以下 ffmpeg -version出现下面结果代表成功 安装whisper pip install openai-whisper在vscode中运行 测试代码 import whisperif __n…

【c++】cout打印char * 或者char[]的细节详解

目录 char* 类型 1.打印指向的字符串 2.打印指针指向的地址 问题描述 解决方法 char型数组 1. 想要输出字符串 2. 想输出字符数组的地址 printf 和cout 的对比 1.打印首字符 2.打印字符串 3.打印字符串首地址 💗感谢阅读!💗 char*…

新火种AI|减脂增肌没捷径?对不起,那是AI 出现以前的事情了...

作者:小岩 编辑:彩云 对于很多人来说,“拥有完美的身材”是人生的重要目标之一,练出好身材的人也会以此为傲,会把自己的好身材po到社交媒体上。换个角度来说,为了让自己社交媒体上的形象足够完美&#xf…

Axure RP下载+详细安装步骤资源百度云盘分享

众所周知,Axure全称“axure rp”,是一款专业的快速原型设计工具。 它能帮助网站需求设计者,快捷而简便的创建基于网站构架图的带注释页面示意图、操作流程图、以及交互设计,并可自动生成用于演示的网页文件和规格文件&#xff0c…

小琳python课堂:Python核心概念 类和对象

大家好,这里是小琳python课堂!今天我们来聊聊Python中的类(Class)和对象(Object),这是面向对象编程(OOP)的核心概念哦!🌟 面向对象编程就像是用“…

基于 INFINI Pizza 为 Hugo 静态站点添加搜索功能

INFINI Pizza 是 INFINI Labs 即将发布的一个基于 Rust 编写的搜索引擎(即将完全开源),目前已经完成基本的搜索能力,并且基于 INFINI Pizza 的核心引擎,提供了一个 WASM 版本的超轻量级内核,可以很方便的嵌…

MicroNet关键代码解读(Micro-block与Dynamic Shift-Max的实现代码)

论文地址:https://arxiv.org/pdf/2011.12289 中文翻译:https://hpg123.blog.csdn.net/article/details/141772832?spm1001.2014.3001.5502 发表时间:2022 项目地址:https://github.com/liyunsheng13/micronet 在MicroNet论文中提…

查文献技巧,数模国赛必须掌握!

参加数学建模竞赛,拿到题目后第一件事就是去查文献,把题目的背景知识看懂。本文介绍查文献的一些技巧。 先看硕博士论文 硕博论文会对研究的问题有详细的背景和基础知识介绍,可帮助我们快速理解题目。 有个经典段子:学士、硕士…

对字符、字符串的研究

每日一背 C的字符串很特殊 //返回字符 char test2() {return p; } //返回整数 int test2() {return 90; } 其实字符串本就是很特殊的存在。字符型、整数算一类,但是字符串型区别前两个类。整数、字符都返回的是一个值,所以可以直接在主函数里面cout不…

《黑神话:悟空》火出圈儿,揭秘幕后实时渲染技术

游戏一度因被贴上“不务正业”、“虚度光阴”的标签而备受争议,然而随着该产业的蓬勃发展,一些游戏被纳入体育竞技项目,如今游戏领域吸引越来越多人的目光。当下火爆全网的《黑神话:悟空》,凭借炫酷逼真的3D效果和独特…

wordpress 页面URL自动跳转到图片地址?

比如你打开关于我们页面: yourdomain.com/about-us/ 结果自动跳转到了: yourdomain.com/wp-content/uploads/2024/08/about-us.jpg 刚开始以为是不是哪里设置了自动跳转,比如YOAST SEO里,但是结果发现不是。 结果发现&#x…

好用的运动耳机品牌推荐?几款开放式蓝牙耳机推荐

论好用的运动耳机推荐,我觉得开放式运动耳机是个不错的选择。主要是因为下面几点: 1舒适度:开放式耳机不封闭耳朵也不塞入耳朵耳道,所以就能够减少长时间佩戴可能造成的压耳感以及不舒服的体验。 2安全性:因为开放式…

鸿蒙(API 12 Beta3版)图形【AR Engine简介】 AR引擎服务

AR Engine(AR引擎服务)是一个用于在HarmonyOS上构建增强现实应用的引擎,提供了运动跟踪、环境跟踪和命中检测等空间计算能力。通过这些能力,您的应用可以实现虚拟世界与现实世界的融合,给消费者提供全新的视觉体验和交…

【数据结构初阶】二叉树--堆(顺序结构实现)

hello! 目录 一、实现顺序结构二叉树 1.1 堆的概念和结构 1.2 堆及二叉树的性质 1.3 堆的实现 1.3.1 创建堆的结构 1.3.2 初始化和销毁 1.3.3 入堆向上调整算法(创建一个小堆) 1.3.4 出堆向下调整算法(小堆&#x…

linux组合命令:删除一个目录树中所有的空目录(包括嵌套空目录)

目录 一、需求 二、实现方式 1、结合使用 find 命令删除空目录 (1)删除目录的方式 (2)只删除空目录 2、更高效的方法 (1)使用 find 搭配 -delete (2)实际效果 三、相关命令…

STM32MP157_uboot_命令使用

STM32MP157_uboot_命令使用 前言: 进入 uboot 的命令行模式以后输入“help”或者“?”,然后按下回车即可查看当前 uboot 所支持的命令,图 中只是 uboot 的一部分命令,具体的命令列表以实际为准。图中的命令并不是 uboo…

SpringBoot2:IOC容器的相关操作以及常用注解说明

一、查看容器中的Bean实例 查看springboot中的容器实例,首先,我们要获取到IOC容器。 //1、返回我们的IOC容器ConfigurableApplicationContext run SpringApplication.run(MainApplication.class, args);//2、查看容器里面的组件String[] names run.ge…

线性代数基础(2)——特征值和特征向量

第一节博客已经整理了求导的公式,一些常用的概念。链接如下:高等数学基础(1)-CSDN博客。 第二节博客整理了微积分的公式及其相关概念。链接如下:高等数学基础(2)——微积分-CSDN博客 第三节博客…