一、文件系统的功能规划

1、引子

咱们花了这么长的时间,规划了会议室管理系统,这样多个项目执行的时候,隔离性可以得到保证。

但是,会议室里面被回收,会议室里面的资料就丢失了。有一些资料我们希望项目结束也能继续保存,

这就需要一个和项目运行生命周期无关的地方,可以永久保存,并且空间也要比会议室大的多。

2、图书馆和文件系统的故事

3、规划文件系统需要考虑的第一点

4、规划文件系统需要考虑的第二点

5、规划文件系统需要考虑的第三点

6、规划文件系统需要考虑的第四点

1、如何避免一定程度上的命名冲突问题

每个文件都有一个名字、这样我们访问一个文件,希望通过它的名字就可以找到

文件名就是一个普通的文本、当然文件名会经常冲突、不同用户取想用的名字的情况还是会经常出现的

如图所示,不同的用户的文件放在不同的目录下,虽然很多文件都叫“文件 1”,只要在不同的目录下,就不会有问题

7、规划文件系统需要考虑的第五点

二、文件系统的相关命令

1、首先是格式化

也即将一块盘使用命令组织成一定格式的文件系统的过程。咱们买个硬盘或者 U盘,经常说要先格式化,才能放文件,说的就是这个。

2、Linux下查看没有格式化的应硬盘信息

# fdisk -l

Disk /dev/vda: 21.5 GB, 21474836480 bytes, 41943040 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk label type: dos
Disk identifier: 0x000a4c75 Device Boot Start End Blocks Id System
/dev/vda1 * 2048 41943006 20970479+ 83 Linux Disk /dev/vdc: 107.4 GB, 107374182400 bytes, 209715200 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes

3、对磁盘进行格式化

mkfs.ext4 /dev/vdc
fdisk /dev/vdc

4、挂在到目录

mount /dev/vdc1 / 根目录 / 用户 A 目录 / 目录 1

格式化后的硬盘,需要挂在到某个目录下面,才能作为普通的文件系统进行访问。

5、卸载挂载

umount / 根目录 / 用户 A 目录 / 目录 1

三、文件系统的相关系统调用

看完了命令行,我们来看一下,如何使用系统调用在操作文件?我们先来看一个完整的例子。

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h> int main(int argc, char *argv[])
{ int fd = -1;
int ret = 1;
int buffer = 1024;
int num = 0; if((fd=open("./test", O_RDWR|O_CREAT|O_TRUNC))==-1)
{
printf("Open Error\n");
exit(1);
} ret = write(fd, &buffer, sizeof(int));
if( ret < 0)
{
printf("write Error\n");
exit(1);
}
printf("write %d byte(s)\n",ret); lseek(fd, 0L, SEEK_SET);
ret= read(fd, &num, sizeof(int));
if(ret==-1)
{
printf("read Error\n");
exit(1);
}
printf("read %d byte(s),the number is %d\n", ret, num); close(fd); return 0;
}

当使用系统调用open 打开一个文件时,操作系统会创建一些数据结构来表示这个被打开的文件下一节,我们就会看到这些。为了能够找到这些数据结构,在进程中,

我们会为这个打开的文件分配一个文件描述符 fd(File Descriptor)。文件描述符,就是用来区分一个进程打开的多个文件的,它的作用域就是当前进程,出了当前进程这个文件描述符就没有意义了

opne返回的fd必须记录好,我们队这个文件的所有操作都要靠这个fd,包括最后关闭文件

1、open函数

2、write函数

3、read函数

4、lseek函数

对于命令行来讲,通过 ls 可以得到文件的属性,使用代码怎么办呢?

我们下面三个函数,可以返回与打开的文件描述符相关的文件状态信息,这个信息将会写到类型为struct stat 的 buf 结构中。

int stat(const char *pathname, struct stat *statbuf);
int fstat(int fd, struct stat *statbuf);
int lstat(const char *pathname, struct stat *statbuf); struct stat {
dev_t st_dev; /* ID of device containing file */
ino_t st_ino; /* Inode number */
mode_t st_mode; /* File type and mode */
nlink_t st_nlink; /* Number of hard links */
uid_t st_uid; /* User ID of owner */
gid_t st_gid; /* Group ID of owner */
dev_t st_rdev; /* Device ID (if special file) */
off_t st_size; /* Total size, in bytes */
blksize_t st_blksize; /* Block size for filesystem I/O */
blkcnt_t st_blocks; /* Number of 512B blocks allocated */
struct timespec st_atim; /* Time of last access */
struct timespec st_mtim; /* Time of last modification */
struct timespec st_ctim; /* Time of last status change */
};

5、stat和lstat的区别

接下来我们来看,如何使用系统调用列出一个文件夹下面的文件以及文件的属性

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <dirent.h> int main(int argc, char *argv[])
{
struct stat sb;
DIR *dirp;
struct dirent *direntp;
char filename[128];
if ((dirp = opendir("/root")) == NULL) {
printf("Open Directory Error%s\n");
exit(1);
}
while ((direntp = readdir(dirp)) != NULL){
sprintf(filename, "/root/%s", direntp->d_name);
if (lstat(filename, &sb) == -1)
{
printf("lstat Error%s\n");
exit(1);
} printf("name : %s, mode : %d, size : %d, user id : %d\n", direntp->d_name, sb.st_mode, sb.st_size, sb.st_uid); }
closedir(dirp); return 0
}

6、opendir函数

7、readdir函数

8、closedir函数

到这里,你应该既会使用系统调用操作文件,也会使用系统调用操作目录了。下一节,我们开始来看内核如何实现的。

四、总结时刻

这一节,我们对文件系统的主要功能有了一个总体的印象,我们通过下面这张图梳理一下

1、在文件系统上,需要维护文件的严格的格式,要通过mkfs.ext4 命令来格式化为严格的格式。

2、每一个硬盘上保存的文件都要有一个索引,来维护这个文件珊国的数据块都保存在哪里

3、文件通过文件夹组织起来,可以方便用户使用

4、为了能够更快读取文件,内存里会分配一块空间最为缓存,让一些数据块放在缓存里面

5、在内核中,要有一整台的数据结构来表示打开的文件

6、在用户态,每个打开的文件都是一个文件描述符,可以通过各种文件相关的系统调用,操作这个文件描述符

趣谈Linux操作系统学习笔记:第二十七讲的更多相关文章

  1. 深挖计算机基础:趣谈Linux操作系统学习笔记

    参考极客时间专栏<趣谈Linux操作系统>学习笔记 核心原理篇:内存管理 趣谈Linux操作系统学习笔记:第二十讲 趣谈Linux操作系统学习笔记:第二十一讲 趣谈Linux操作系统学习笔 ...

  2. 趣谈Linux操作系统学习笔记:第二十讲

    一.引子 1.计算两方面的原因 2.内存管理机制 二.独享内存空间的原理 1.会议室和物理内存的关系 和会议室一样,内存都被分成一块块儿的,都编号了号,例如3F-10就是三楼十号会议室.内存页有这样一 ...

  3. 趣谈Linux操作系统学习笔记:第二十一讲

    一.分段机制 1.分段机制的原理图 2.段选择子 3.段偏移量 例如,我们将上面的虚拟空间分成以下 4 个段,用 0-3 来编号.每个段在段表中有一个项,在物理空间中,段的排列如下图的右边所示. 4. ...

  4. 趣谈Linux操作系统学习笔记:第二十四讲

    一.小内存的分配基础 1.kmem_cache_alloc_node的作用 通过这段代码可以看出,它调用了kmem_cache_alloc_node函数,在task_struct的缓存区域task_s ...

  5. 趣谈Linux操作系统学习笔记:第二十五讲

    一.mmap原理 在虚拟内存空间那一节,我们知道,每一个进程都有一个列表vm_area_struct,指向虚拟地址空间的不同内存块,这个变量名字叫mmap struct mm_struct { str ...

  6. 趣谈Linux操作系统学习笔记:第二十六讲

    一.内核页表 和用户态页表不同,在系统初始化的时候,我们就要创建内核页表了 我们从内核页表的根swapper_pg_dir开始找线索,在linux-5.1.3/arch/x86/include/asm ...

  7. 趣谈Linux操作系统学习笔记:第二十八讲

    一.引子 磁盘→盘片→磁道→扇区(每个 512 字节) ext* 定义文件系统的格式 二.inode 与块的存储 1.块 2.不用给他分配一块连续的空间 我们可以分散成一个个小块进行存放 1.优点 2 ...

  8. 趣谈Linux操作系统学习笔记:第二十九讲

    一.引子 在这之前,有一点你需要注意.解析系统调用是了解内核架构最有力力的一把钥匙,这里我们只要重点关注这几个最重要的系统调用就可以了 1.mount 系统调用用于挂载文件系统:2.open 系统调用 ...

  9. 《趣谈 Linux 操作系统》学习笔记(一):为什么要学 Linux 及学习路径

    前言:学习的课程来自极客时间的专栏<趣谈 Linux 操作系统>,作者用形象化的比喻和丰富的图片让课程变得比较易懂,为了避免知识看过就忘,打算通过写学习笔记的形式记录自己的学习过程. Li ...

随机推荐

  1. Web支持HTTPS的client(HTTP&XML-RPC)

    生成Web自签名的证书(在命令行执行以下命令) keytool -genkey -keysize 2048 -validity 3650 -keyalg RSA -dname "CN=Han ...

  2. ElasticSearch6.3.2 集群做节点冷(warm) 热(hot) 分离

    拿一个小规模的5节点ES集群做冷热分离尝试,它上面已经有60多个索引,有些索引按月.每月生成一个索引,随着数据的不断写入,历史数据(只需保留三个月数据,三个月之前的数据视为历史数据)越来越占磁盘空间和 ...

  3. Appium+python自动化(五)- 模拟器(超详解)

    简介 Appium是做安卓自动化的一个比较流行的工具,对于想要学习该工具但是又局限于或许当前有些小伙伴没 android 手机来说,可以通过安卓模拟器来解决该问题,下面就讲解使用appium连接安卓模 ...

  4. R与金钱游戏:均线黄金交叉1

    双11临近的我发现自己真的很穷很穷很穷(重要的问题说三遍)-- 贫穷催人上进.于是我就寻思着在空闲时间自己捣鼓一下钱生钱的游戏是怎么玩的,毕竟就算注定做韭菜也要做一根有知识有理想的韭菜. 第一个要玩的 ...

  5. Wait… What Happens When my React Native Application Starts? — An In-depth Look Inside React Native

    Discover how React Native functions internally, and what it does for you without you knowing it. Dis ...

  6. uni-app如何解决在for循环里调用异步请求获取数据顺序混乱问题?

    总结/朱季谦 先前有一次做uni-app的js接口对接时,遇到过这样的情况,在for循环里,调用一个异步请求时,返回来的值顺序是乱的,因此,在以下的代码里,push到数组里的值,每次的顺序可能都是不一 ...

  7. pod install速度慢,pod repo update 速度慢解决方法

    相信大家已经感受到pod install速度越来越慢了,网上提供了几种解决方案,但是都没有完全解决速度慢的问题. 使用国内镜像的Specs 在pod install时使用命令pod install - ...

  8. Asp.NetCoreWebApi入门 - 从零开始新建api项目

    开发环境 打开VS,建立项目 项目结构 修改 StartUp 类代码 ConfigureServices方法 Configure方法 为开发环境和生产环境配置不同的 Startup 新建一个Contr ...

  9. 检测代码潜在bug和质量之SonarQube

    参数使用 项目分析参数可以在多个地方设置,继承关系如下: 全局分析参数,通过Web UI设置,作用于所有项目(配置–>通用–>通用中设置) 项目分析参数,通过WebUI设置,覆盖全局参数( ...

  10. sedlauncher.exe 磁盘爆满

    打开应用和功能,搜KB4023057,然后卸载. 快捷键WIN+R打开运行,输入services.msc回车打开系统服务,找到Windows Remediation Service (sedsvc)和 ...