Linux文件系統
Linux文件系統(一)文件系統概述
一、文件系統的功能規劃
文件系統是用來管理磁盤空間,存儲文件的一套軟件,它需要滿足下面幾個特點
-
文件系統要有嚴格的組織形式,使得文件能以塊爲單位存儲
-
文件系統需要索引區,用來查找存儲文件的多個塊存放在哪個區域
-
如果文件系統的某個文件時熱點文件,最近經常被訪問,那麼文件系統應該有緩存層
-
文家應該用文件節夾的形式組織起來,方便管理和查詢
-
Linux內核在內存中應該維護一套數據結構,來維護對應進程打開的文件
二、文件系統相關的命令
對於一塊磁盤,首先需要格式化才能存放文件,Linux下常用的文件系統格式爲 ext3 和 ext4
可以使用命令 fdisk -l
查看磁盤的分區情況
# 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
例如上面 vda,大小爲 21.5 G,有一個分區 vda1
vdc,大小爲 107.4 G,沒有被分區
可以使用 mkfs.ext3
和 mkfs.ext4
進行格式化
mkfs.ext4 /dev/vdc
執行完命令後,vdc 會建立一個分區,格式化爲 ext4 格式
也可以選擇不把一個磁盤格式化爲一個分區,而是分爲好幾個分區,然後分別格式化
首先通過 fdisk
啓動一個交互程序
fdisk /dev/vdc
輸入 p
可以顯示當前的分區信息
輸入 n
(new)新建一個分區,它會讓你選擇創建一個主分區 primary,還是擴展分區 extended。我們一般都會選擇 primary
接下來會讓你輸入分區號,如果原來沒有分區,那麼應該時從 1 開始的,直接按回車默認也行
接下來,可以一路選擇默認值,直到讓你輸入分區的大小,通過 +sizeM 或者 +sizeK 的方式,默認值是整塊磁盤都用上。可以輸入 +5620M 來創建一個 5G 的分區。這時候輸入 p 就可以看到分區信息,然後再輸入 w 將分區信息寫入磁盤中
分區結束後,可能會出現 vdc1,vdc2 等多個分區,這時候可以通過 mkfs.ext3 /dev/vdc1
將第一個分區格式化爲 ext3 格式。通過 mkfd.ext4 /dev/vdc2
將第二個分區格式化爲 ext2 格式
格式化後需要掛載到某個目錄下,才能訪問
mount /dev/vdc1 / 根目錄 / 用戶 A 目錄 / 目錄 1
需要卸載可以通過下面命令
umount / 根目錄 / 用戶 A 目錄 / 目錄 1
Linux下一切皆文件。可以使用 ls -l
查看文件的類型
- -:普通文件
- d:文件夾
- c:字符設備文件
- b:塊設備文件
- s:socket文件
- l:軟鏈接文件
# ls -l
lrwxrwxrwx 1 root root 61 Dec 14 19:53 instance -> /var/lib/cloud/instances
三、文件系統相關的調用
操作文件可以通過下面的方法
#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:打開一個文件
- write:往文件裏寫內容
- lseek:移動文件指針
- read:讀取文件內容
- close:關閉文件
獲取文件信息可以通過下面三個系統調用
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:通過文件路徑獲取文件的 stat 信息,無法查看軟鏈接文件
- fstat:通過文件描述符獲取文件信息
- 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:關閉一個目錄
- dirent:表示目錄下一個項
四、總結
- 在文件系統上,需要維護文件嚴格的格式,需要通過 mkfd.ext4 來講分區格式化爲 ext4 格式
- 每一磁盤保存文件都需要一個索引,來維護對應文件存儲在磁盤上的位置
- 文件通過文件夾組織起來,方便管理
- 爲了快速讀取文件,內核分配了一塊空間作爲緩存,讓一些數據塊存儲在緩存裏面
- 在內核中,要有一套數據結構來表示進程打開的文件
- 在內核態,每個打開的文件都有一個文件描述符,文件相關的操作都需要通過這個文件描述符找到對應的文件