趣谈Linux操做系统学习笔记:第二十七讲

1、文件系统的功能规划

一、引子

我们花了这么长的时间,规划了会议室管理系统,这样多个项目执行的时候,隔离性能够获得保证。node

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

这就须要一个和项目运行生命周期无关的地方,能够永久保存,而且空间也要比会议室大的多。bash

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

三、规划文件系统须要考虑的第一点

四、规划文件系统须要考虑的第二点

 

五、规划文件系统须要考虑的第三点

六、规划文件系统须要考虑的第四点

一、如何避免必定程度上的命名冲突问题数据结构

每一个文件都有一个名字、这样咱们访问一个文件,但愿经过它的名字就能够找到ide

文件名就是一个普通的文本、固然文件名会常常冲突、不一样用户取想用的名字的状况仍是会常常出现的函数

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

七、规划文件系统须要考虑的第五点

2、文件系统的相关命令

一、首先是格式化

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

二、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

三、对磁盘进行格式化

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

四、挂在到目录

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

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

五、卸载挂载

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

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

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

#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,包括最后关闭文件

一、open函数

二、write函数

三、read函数

四、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 */
};

 五、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
}

六、opendir函数

七、readdir函数

八、closedir函数

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

 4、总结时刻

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

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

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

三、文件经过文件夹组织起来,能够方便用户使用

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

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

六、在用户态,每一个打开的文件都是一个文件描述符,能够经过各类文件相关的系统调用,操做这个文件描述符

相关文章
相关标签/搜索