在linux 中的文件系統(tǒng)中,文件=N(N>=1)個(gè)inode +M(M>=1)個(gè)數(shù)據(jù)塊。
數(shù)據(jù)塊,存放文件的內(nèi)容數(shù)據(jù),數(shù)據(jù)塊的數(shù)目根據(jù)文件內(nèi)容的大小而定。
inode稱為信息節(jié)點(diǎn),其作用有二:1、存儲跟文件相關(guān)的屬性信息,如修改時(shí)間、所有者、文件類型和文件長度,注意這些信息里并沒有文件名;2、存儲指向文件內(nèi)容數(shù)據(jù)塊的指針信息。
在一個(gè)文件系統(tǒng)中,一個(gè)inode代表一個(gè)文件,并使用一個(gè)整數(shù)值來標(biāo)志該inode,稱為inode-number,該值對于一個(gè)文件系統(tǒng)而言是唯一的,即通過該值可以找到其對應(yīng)的inode。一般情況下,一個(gè)文件只有一個(gè)inode信息用來描述它。

目錄,在linux中,其實(shí)也是一種文件,所以它也是由“inode+數(shù)據(jù)塊”構(gòu)成的。而其文件內(nèi)容是一個(gè)列表,每一個(gè)列表項(xiàng)記錄“inode-number+filename"。
因此,我們通常所說的目錄a"包含"文件b,其實(shí)現(xiàn)層面上的意思是,目錄a的內(nèi)容列表里有一個(gè)關(guān)于文件b的列表項(xiàng),即“b的inode-number+ b的filename”。
綜上,linux中,一個(gè)文件(包括目錄)的文件名,及文件名與inode的對應(yīng)關(guān)系,都是由包含該文件的目錄所描述的。
其中,有兩個(gè)特殊的文件名“.” 和 “..”,“.”代表當(dāng)前目錄自身,".."代表包含當(dāng)前目錄的上一級目錄。
linux 文件系統(tǒng)樹:
實(shí)現(xiàn)代碼:/********************************** *簡單實(shí)現(xiàn)pwd命令 *參照:實(shí)驗(yàn)樓 *********************************/#include <stdio.h>#include <stdlib.h>#include <dirent.h>#include <sys/types.h>#include <sys/stat.h>#include <string.h>#include <unistd.h>#define MAX_DIR_DEPTH (256) //限制最大的目錄深度#define TRUE 1#define FALSE 0//根據(jù)文件名獲取文件的inode-numberino_t get_ino_byname(char *filename){ struct stat file_stat; if(0 != stat(filename, &file_stat)) //stat()通過文件名filename獲取文件信息,并保存在buf所指的結(jié)構(gòu)體stat中 { perror("stat"); exit(-1); } return file_stat.st_ino;}//根據(jù)inode-number, 在當(dāng)前目錄中查找對呀的文件名char *find_name_byino(ino_t ino){ DIR *dp = NULL; struct dirent *dptr = NULL; char *filename = NULL; if(NULL == (dp = opendir("."))) //opendir()打開一個(gè)目錄,在失敗的時(shí)候返回一個(gè)空的指針,成返回DIR結(jié)構(gòu)體 { fPRintf(stderr, "Can not open Current Directory/n"); exit(-1); } else { while(NULL != (dptr = readdir(dp))) //readdir()用來讀取目錄。返回是dirent結(jié)構(gòu)體指針 { if(dptr->d_ino == ino) { filename = strdup(dptr->d_name); //strdup()將串拷貝到新建的位置處,返回一個(gè)指針,指向?yàn)閺?fù)制字符串分配的空間;如果分配空間失敗,則返回NULL值. break; } } closedir(dp); } return filename;}int main(int argc, char *argv[]){ //記錄目名的棧 char *dir_stack[MAX_DIR_DEPTH]; unsigned current_depth = 0; while(TRUE) { ino_t current_ino = get_ino_byname("."); //通過特殊的文件名"."獲取當(dāng)期目錄的inode-number ino_t parent_ino = get_ino_byname(".."); //通過特殊的文件名".."獲取當(dāng)前目錄的父目錄的inode-number if(current_ino == parent_ino) break; //達(dá)到根目錄,推出循環(huán) /*兩個(gè)inode-number不一樣*/ chdir(".."); //更改當(dāng)前工作目錄,變?yōu)楫?dāng)前目錄的父目錄 dir_stack[current_depth++] = find_name_byino(current_ino); //"文件名"地址存放 if(current_depth >= MAX_DIR_DEPTH) //路徑名太深 { fprintf(stderr, "Directory tree is too deep./n"); exit(-1); } } int i = current_depth - 1; for(i = current_depth - 1; i >= 0; i--) //打印路徑 { fprintf(stdout, "/%s", dir_stack[i]); } fprintf(stdout, "%s/n", current_depth == 0 ? "/" : ""); return 0;}/********************************************************************dirent結(jié)構(gòu)體:struct dirent{ long d_ino; //inode number 索引節(jié)點(diǎn)號 off_t d_off; //offset to this dirent 在目錄文件中的偏移 unsigned short d_reclen;// length of this d_name 文件名長 unsigned char d_type; //the type of d_name 文件類型 char d_name [NAME_MAX+1]; //file name (null-terminated) 文件名,最長255字符};DIR結(jié)構(gòu)體:struct __dirstream{ void *__fd; // `struct hurd_fd' pointer for descriptor. char *__data; // Directory block. int __entry_data; // Entry number `__data' corresponds to. char *__ptr; // Current pointer into the block. int __entry_ptr; // Entry number `__ptr' corresponds to. size_t __allocation;// Space allocated for the block. size_t __size; // Total valid data in the block. __libc_lock_define (, __lock) // Mutex lock for this structure.};typedef struct __dirstream DIR;結(jié)構(gòu)體stat:struct stat { dev_t st_dev; //文件的設(shè)備編號 ino_t st_ino; //節(jié)點(diǎn) mode_t st_mode; //文件的類型和存取的權(quán)限 nlink_t st_nlink; //連到該文件的硬連接數(shù)目,剛建立的文件值為1 uid_t st_uid; //用戶ID gid_t st_gid; //組ID dev_t st_rdev; //(設(shè)備類型)若此文件為設(shè)備文件,則為其設(shè)備編號 off_t st_size; //文件字節(jié)數(shù)(文件大小) unsigned long st_blksize; //塊大小(文件系統(tǒng)的I/O 緩沖區(qū)大小) unsigned long st_blocks; //塊數(shù) time_t st_atime; //最后一次訪問時(shí)間 time_t st_mtime; //最后一次修改時(shí)間 time_t st_ctime; //最后一次改變時(shí)間(指屬性)};********************************************************************/參考:實(shí)驗(yàn)樓參考資料《Unix環(huán)境高級編程》
新聞熱點(diǎn)
疑難解答