当前位置:网站首页>基础IO(上):文件管理和描述符
基础IO(上):文件管理和描述符
2022-08-02 03:32:00 【RNGWGzZs】

-----------------"如果说,非要一个人去的抗。那就让我去吧"
目录
缓冲区:外设文件依据冯诺依曼体系下,效率低。这是一种平衡方法。
(1)复习回顾(C提供文件操作接口):
我们先来回顾在C语言时期,用的C文件接口。
①文件打开以及文件生成位置。
我们先看看fopen函数:

问:我们常说,文件在当前可执行程序目录生成,这对不对呢?

此时我们让进程跑起来。
//先找到进程pid
ps ajx | grep test
//我们知道不止上面这一种查看进程id的做法
ls /proc/+(进程id)
也就是,cwd和exe目录重叠了。
所以我们退回一层目录,

发现文件生成已经不在可执行目录中了。所以,应当是进程运行路径作为文件生成的地方。
② 写入与输出
fputs:

向文本写入。


操作系统会默认给我们打开三个流: stdin stdout stderr.
向stdout(显示器)输出:


当然,你定听过,linux下一切皆文件。
那么该如何理解呢?

fgets:

从键盘获取


(2)系统调用接口:
不管是C\C++都有自己的一套文件调用接口。但他们从根本上都会去调用,系统层面上的接口。
//C库提供接口
fopen fclose fwrite fread
//系统文件调用
open close write read①open\close:


打开文件的flag有多种方式,mode后面指的是文件创建的权限(default & (~umask))
| flag参数 | 说明 |
| O_RDONLY | 只读打开 |
| O_WRONLY | 只写打开 不具备创建文件 |
| O_RDWR | 读写打开 |
| O_CREAT | 若文件不存在,则会先创建再打开通常和(打开连用),并需要指名文件权限mode |
| O_APPEND | 对标fopen("a") |

flag按照比特位设计的多种参数:
宏判断,多种选项。
②write\read:


(3)文件描述符:
在open中,成功打开文件会返回int类型的值,这个就是文件描述符。
①文件描述符从0开始,并默认0 1 2给三流
连续打开几个文件。

并把文件描述符号打印出来:

可以从现象中看到,文件描述符呈递增状态。 但为什么是从3 开始呢?
在前面已经说过,程序运行起来,C会默认打开三个流:
stdin\stdout\stderr,他们的文件描述符分别是0、1、2.

怎么验证呢?

首先我们让printf打印这个 字符串在屏幕上。

close(1);

此时我们发现,什么也没打印。
②文件描述符分配规则: 

本来是是向stdout 打印数据的,但因为关闭了,而创建的fd 又被分配了1
所以直接写入到了文件中。 这也叫做输出重定向。
重定向的本质:修改文件描述符指向的FILE* 。
重定向与缓冲区:
下面我们来看看这个代码:

关闭了stdout,那么本来是向stdout写入的,重定向到了log.txt当中。

对代码进行一定修正后:
怎么没写到log里面?

因为把数据写到文件内,不是直接在内存上操作,而需要首先把数据写在缓冲区:

这也就是输入重定向;
缓冲区:外设文件依据冯诺依曼体系下,效率低。这是一种平衡方法。
1.无缓冲
2.行缓冲 以"\n"为标志 进行刷新
3.全缓冲 文件写入(磁盘)
缓冲区在哪里??
由谁提供?
操作系统有缓冲?与之有什么关系?
下面的代码会解答:

利用不同接口在屏幕上打印字符串。
添加fork();
为什么重定向到log内,会变多呢?!

所以,缓冲区的概念,是语言提供自带的。

默认打开流 与 文件标识符:
stdout(FILE* )-----> 1(fd).
FILE是一个结构体 ,封装了fd
所以stdout-->FILE对象(fd=1) 只认准下标,但不关心内容~
(4)文件管理
当进程运行,调用文件函数,打开文件。多个进程就可以打开多个文件。所以我们就需要操作系统,对这些文件进行管理。
管理的本质: 先描述 再组织。
//文件信息(内容+属性)
strcut file
{
int _fd;
}
进程与文件的关系:
磁盘文件vs内存文件
磁盘文件:内容+属性。
内存文件:更多的是属性信息。
(5)使用dup2:

简单来说,就是让旧的描述符 拷贝 新的文件描述符。即,对new重定向。

把fd1的内容 覆盖式写入到1里面。
感谢你的阅读
祝你好运~
边栏推荐
猜你喜欢
随机推荐
GM8775C MIPI转LVDS调试资料分享
联阳IT6561|IT6561FN方案电路|替代IT6561方案设计DP转HDMI音视频转换器资料
【Popular Science Post】Detailed explanation of MDIO interface
HDMI转MIPI CSI东芝转换芯片-TC358743XBG/TC358749XBG
最第k大的数的一般性问题
如何使用 PHP 实现网页交互
How to remotely debug PLC?
所有子字符串中的元音 —— LeetCode - 2063
【Arduino 连接GP2Y1014AU0F 灰尘传感器】
树莓派入门(1)系统镜像烧录
使用buildroot制作根文件系统(龙芯1B使用)
【plang 1.4.4】编写贪吃蛇脚本
判断子序列 —— LeetCode-392
Arduino点亮数码管
联阳IT66121FN提供SDI转HDMI方案分享
Typora use
【科普贴】SD卡接口协议详解
GM7150 CVBS转BT656视频解码芯片详细内容及设计要求
兼容C51与STM32的Keil5安装方法
MPU6050 加速度计和陀螺仪传感器与 Arduino 连接



![[Arduino uses a rotary encoder module]](/img/2a/43ffe782d6d5aa9f38f875bb5d98b1.png)






