【linux】基础IO(一)

文件只有站在系统层面才能彻底理解

简单回顾一下文件:

首先我们要明确一点,我们说的打开文件不是写下fopen就打开文件,而是当我们的进程运行起来,进程打开的文件。

我们在C语言一般都会使用过如下的代码进行向文件中写入在这里插入图片描述
但是除了此方法我们还有重定向也可以向文件中写入。
重定向的性质

  • 当没有文件时创建文件,有文件时清空文件
  • 将原本向一个文件输出的数据转移到另一个文件
    在这里插入图片描述

同样,我们也可以使用"a"追加重定向进行追加
在这里插入图片描述
在这里插入图片描述
故我们由此可以得出一个结论:重定向一定是与文件操作有关的。

提炼一下对文件的理解:

我们已经说过,是进程在打开文件,那么文件没有被打开的时候,文件在哪里?
答案是在磁盘中。

我们的一个进程可以打开多个文件,同时我们也可以同时运行多个进程。那么OS是不是要将进程进行管理呢?
答案是一定的,我们要用到先描述在组织的思想进行管理
于是我们可以预测一波,OS内部一定有类似PCB的内核数据结构

那么此时我们有个疑问?
每种语言对文件的操作都不一样,这样我们的学习成本岂不是大大增加了吗,为什么要这样做呢?

理解文件:

a. 操作文件,本质是进程在操作文件。
b. 文件->磁盘->外设->硬件->向文件中写入,向硬件中写入->OS是硬件的管理者->我们通过OS进行文件写入->我们不能直接向操作系统写入(操作系统必须确保硬件的良好运行防止数据被污染)->操作系统提供系统调用函数->我们使用C语言的fprintf,fread…是对系统调用的封装。

那么问题来了,我们为什么要使用系统调用呢?
怎么使用呢?(这个先不提)

使用系统调用函数:

既然是对系统调用的封装,那我们先看看系统调用的代码&&现象:
在此之前我们贴一下需要用到的系统调用函数。

打开文件:
在这里插入图片描述
关闭文件:
在这里插入图片描述
写入:
在这里插入图片描述


代码实践:

在这里插入图片描述
第二个的第一个参数为三个,先来解释一下这三个的含义,
不存在就创建,只写入,重新打开会清空。

现象:
在这里插入图片描述
于是现在我们有两个疑问:

  1. 0666是什么
  2. O_CREAT …是什么

对于1,我们在上图已经展示过open有两个形式,虽然像重载但不是重载!
第一个open一般是针对已经创建好的文件,第二个是还没有创造的文件。
0666就代表当前文件的权限。

那么我们的文件就应该是rw_rw_rw在这里插入图片描述
但是却不是,这是由于我们的mask值在作祟,我们设置的权限会与mask值做一系列操作变成图示权限。

我们也可以更改mask。在这里插入图片描述

在这里插入图片描述
对于第二个问题,这其实是OS系统调用接口的一种常见的方法,这个方法叫做位图,我们的一个int是有32的比特位的,故我们可以利用位操作来进行控制32个比特位。

具体看如下代码,宏应该用大写!!我太懒就没改了,要大写!在这里插入图片描述
在这里插入图片描述

于是我们就大概的了解了这些函数参数的意义。
此时我们也发现一个事情:
就是我们上图的系统调用与C语言的fopen的"w"很相似,他们有什么联系呢?

同时,我们将O_TRUNC换为O_APPEND即可得到与fopen的"a"很相似,那么他们又有什么关系呢?

另外,我们经过程序验证,在这里插入图片描述
在这里插入图片描述
发现没有0 1 2,这三个是什么文件呢?
答案是在这里插入图片描述
这是不是也与我们C语言默认就有的三个流一样呢?
这三者到底有什么关系ne?

在这之前,我们还要有两个东西要理解:
fd一切皆文件

fd的理解:

fd是每个文件都会有的唯一标识符。

我们已经说过,OS对于文件的管理一定也会有内核数据结构的存在。

在这里插入图片描述
图示并不完整,struct file还指向一块缓冲区与方法表(方法表等会会提到)

那么看完上图后,fd是啥我们依旧不知道呀。

当我们向一个文件写入时,当前进程会根据你穿给write的下标找到文件描述符表对应的下标,找到对应的struct_file对应的缓冲区写入,没错,文件描述表的下标记就是fd!!

一切皆文件:

我们fd的0 1 2是默认打开的,为什么可以把硬件当做文件打开呢?

一切皆文件这个概念如何理解呢?
接下来我们一起探究一下。

在这里插入图片描述
于是,在linux下一切接文件!!

解决上边的三个问题:

我们在访问文件时,OS只认fd,所以,FILE内部一定有fd,一定是对系统调用的封装。
在这里插入图片描述
现象:
在这里插入图片描述
C语言中的标准输入(stdin)、标准输出(stdout)和标准错误(stderr)本质上是对进程默认打开的文件描述符的封装。

为什么要封装呢?

为了语言的跨平台性!

linux,windows,macos等等操作系统的文件操作的系统调用的接口必然是不一样的,若我们使用系统调用,就会失去语言的跨平台性!

所以所有的语言都想有跨平台性,所以必须封装->不同语言封装的接口就会出现差别了。


欲知后事如何,请看下回分解~~

  • 23
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值