Linux 一切皆文件

我们在Linux中所熟知的一句话“一切皆文件”,所以在Linux操作系统中,所有的研究实际上就是研究文件,所以我们也有必要了解文件系统。

系统文件相关接口

我们在学C的时候,学过文件相关的接口,这些都是C标准库中的函数,称为库函数。而我们现在要学的接口是系统提供接口,称之为系统调用接口。我们用这些接口对文件进行操作。

那么系统调用接口有哪些呢?
open、write、iseek
上述接口具体用法,可以查看man手册,非常清楚。

此处我们主要来看看open函数:
int open(const char* filename,int flags,mode_t mode);
filename要打开文件的名称
flags以什么属性打开文件
O_RDONLY:以只读的形式打开文件
O_WRONLY:以只写的形式打开文件
O_RDWR:以可读可写形式打开文件
上述三个属性必须有一个。
O_CREAT:若文件不存在则创建。(此时就需要mode来指明新文件权限)
O_APPEND:以可追加的形式打开文件。
mode打开文件后给文件设置的默认权限。
返回值
成功:新打开文件的文件描述符
失败:-1

我大家可能有疑问了,什么是文件描述符?下面我们来介绍一下文件描述符fd。

文件描述符

Linux内核利用文件描述符来访问文件,当我们打开一个新的文件就会给我们返回一个对应文件描述符(一个非负的小整数)。
Linux进程中会默认打开三个文件描述符,分别是标准输入0,标准输出1,标准错误2。
这三个文件描述符0,1,2分别对应的物理设备是:键盘,显示器,显示器。

我们用图再来理解一下:
在这里插入图片描述
通过上图我们发现在PCB中有一个结构体指针files,指向一个file_struct结构体,在这个结构体中有一个指针数组fd_array,里面保存的指针就是打开的文件指针,数组的下标就是我们获得的文件描述符。所以拿到文件描述符就可以找到对应的文件,从而访问文件的信息。

那么文件描述符是怎么分配的呢?
我们知道在Linux下系统会默认打开三个文件,也就是0,1,2。当我们打开一个文件时,会在file_struct数组当中找一个没有被使用的最小下标,来作为我们打开文件的描述符。

重定向

看一段代码

#include<stdio.h>
#include<iostream>
#include<unistd.h>
int main()
{
	close(1);
	int fd =open("my",O_WRONLY|O_CREAT,0777);
	printf("fd:%d\n",fd);
	fflush(stdout);
	close(fd);
	return 0;
}

在这里插入图片描述
通过结果我们发现本应该输出在屏幕上的内容,没有输出,而是输出到了文件中。这种现象就是重定向,这是因为我们将标识符1也就是标准输出关闭了,当我们创建一个新文件,根据标识符的分配规则,打开的文件的标识符就是1,所以我们本该输出的内容,写到了文件内,而没有输出到屏幕上。

画个图理解一下
在这里插入图片描述
这里介绍一个函数:

int dup2(int oldfd ,int newfd)
功能:重定向
newfd:会关闭这个文件描述符,并将newfd拷贝到oldfd上。
oldfd:要重定向到哪个文件描述符上。

FILE

1.因为IO相关函数与系统调用接口对应,并且库函数封装系统调用,所以本质上,访问文件都是通过fd访问的。
2.因此C库中的FILE结构体,必定封装了fd。

文件系统

当我们输入ls -l 命令时,我们会看到如下图:
ls -l是读取存储在磁盘上的文件信息。
在这里插入图片描述
从左往右依次是:文件类型-》权限-》硬链接数-》文件拥有者-》文件拥有者组-》大小-》最后修改时间-》文件名。

当我们输入stat 文件名就可以获得文件的更多信息
在这里插入图片描述

我们发现图中有一个Inode,那么这个Inode是干什么的呢?
Inode号码就是区分文件的,因为我们的文件名重复的有很多,所以每一个文件有自己的Inode号码,那么Inode号码是怎么来的呢?这就需要了解一下文件系统。

在这里插入图片描述

上图大概是我们的文件管理系统,我们主要观察的是:
超级块(Super Block):存储的是文件系统本身信息。比如:Block和Inode总量。
块位图(Block Bitmap):记录着DataBlock中哪个数据块没有被占用,哪个块被占用了。
Inode位图(inode Bitmap):每一个比特表示一个Inode号码是否可以用。
Inode结点表(inode Table):保存文件的信息。如:大小、所有者、最近修改时间。
数据区(Data Block):存放文件数据。

当我们创建一个文件,首先要在块位图中找有没有空闲的块,将待存储的文件数据分成不同的块放在数据区,此时需要用inode结点来存储文件的信息,所以就会去inode位图里找空闲的inode结点,将文件信息存储到inode结点里,并将结点放在inode结点表里。最后将文件名称和inode结点当做目录的目录项存储起来。
此时文件和inode结点之间的对应关系就可以让操作系统将文件名与文件内容相联系。

但我们查找一个文件时,先找到文件对应的inode结点,通过inode的结点找到数据区中存储文件数据对的块,将这些快合并在一起就是文件数据了。

硬链接

通过上述知识我们发现,其实找一个文件并不是找一个文件的文件名,而是找到其对应的inode结点。然而在Linux下可以让多个文件对应同一个inode结点。也就说多个文件名可以访问到同一个inode结点对应的内容,这就叫硬链接。
如何建立硬链接呢?

ln [源文件][链接出来的文件名称]
在这里插入图片描述
hello.c是我们创建出来的硬链接。我们发现hello.c和test.c有相同的inode码,所以他们可以访问同一片区域。尽管此时将删除一个硬链接,而另一个仍可以使用,这种一般用作来备份重要文件。

软连接

软连接相当于创建了一个新的文件,这个文件里存储的是源文件的路径,通过这个路径找到源文件的数据。
如何建立软链接呢?
ln -s [源文件][链接出来的文件名称]
在这里插入图片描述
hh使我们软链接创建出来的,我们发hh与test的inode码不同,说明他们有自己独立的inode结点,内容不同。hh保存的是test的路径,所以我们执行hh的时候,就相当于执行了test。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值