趣談Linux操作系統學習筆記:第二十七講


一、文件系統的功能規划

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、在用戶態,每個打開的文件都是一個文件描述符,可以通過各種文件相關的系統調用,操作這個文件描述符

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM