Linux的文件操作系统结构

    科技2022-07-17  114

    最近在学习Linux C,其中涉及到了对文件的一些操作,这里对Linux文件操作系统结构进行了部分介绍。主要是为了方便以后自己查阅!!!整体的时候可能有不准确或者有错误的地方,若能指出则十分感谢。转载请标明出处,谢谢!


    目录

    一、Linux文件系统的介绍

    二、Linux文件系统的组成 

     2.1 超级块

     2.2 索引节点

    三、Linux文件属性的操作方法

    例一:使用stat函数获得指定文件的属性


    一、Linux文件系统的介绍

            Linux采用了目录树的格式来管理所有的文件和目录(在Linux中目录其实也是一个文件);和DOS或Windows不同的时LInux的树形目录中只有唯一的一个根目录“/”(称为根,root),其他目录都是这个根目录衍生的子目录,如图1和图2分别是DOS/Windows和Linux的目录树文件结构。

     

                                        

                                                                图1 DOS/Windows的目录树文件结构

     

                 

                                                                         图2 Linux的目录树文件结构

    在Linux中,所有的内容都被看成文件,包括硬件和目录;所有的操作都可以归结为对文件的操作,Linux可以像操作普通文件一样来对磁盘文件、串口、键盘、显示器、打印机以及其他的设备进行操作。 

            Linux的文件系统是目录和文件的一种层次安排,目录的起点称为根(root),即一个字符”/“ ;

            目录(directory)是一个包含目录项的文件,在逻辑上,可以认为每个目录项都包含一个文件名,同时还包含说明该文件属性的信息。通过这种树形等级结构,用户可以浏览整个系统,可以进入任何一个已授权的目录并且访问相应的文件。

     

    二、Linux文件系统的组成 

             Linux的文件系统由如下4部分组成:引导块、超级块、索引节点表和数据块,对各个部分的详细说明如下:

    引导块:用于存放文件系统的引导程序,引导程序是用于系统引导或启动操作系统。如果一个文件系统不存放操作系统,其引导块将为空。超级块:用来描述该文件系统管理的资源,其包含空闲索引节点表和空闲数据块表,用于是具体说明文件系统的资源使用情况。索引节点表:用来存储文件的控制信息,每个节点对应一个文件。数据块:是磁盘上存放数据的磁盘块,包括目录文件和数据。

     

               

                                                                              图3 Linux文件系统的组织结构:

            这4个部分最重要的是超级块和索引节点表,它们都是用于描述当前文件系统状态的组成。

    2.1 超级块

            超级块用于描述Linux文件系统的资源状态,包括文件系统的大小、空闲单元位置信息等,在文件系统对文件的管理中起到至关重要的作用,其由如下字段构成:

    文件系统的容量信息,如数据块数目、保留块数目和块的大小等文件系统中空闲块的数目文件系统中部分可用的空闲块表空闲块表中下一个空闲块号索引节点表的大小文件系统中部分空闲索引节点表空闲索引节点表中下一个空闲索引节点号超级块的锁字段,用于保证对存储单元的互斥操作空闲块表的所字段和空闲索引节点的锁字段超级块是否被修改的标志其他字段,存放了文件系统是否完整的标志

    注意:在Linux关机的时候要求先将缓冲区数据写回文件系统,并且卸载该文件系统,如果没有现在该文件系统就关机,则很可能导致数据丢失;

              而在Linux启动的时候,再令挂在一个文件系统之前之前会先去检查其超级块中的相应字段,如果上次没有进行卸载操作,则需要对该文件系统的完整性进行检查。 

     2.2 索引节点

            超级块给出的是为文件系统的相关信息,而一个文件信息则是由索引节点表(inode)给出,每个文件都有自己的索引节点表,在其中包含了该文件数据在磁盘上存储的位置、操作权限、文件所有者、操作时间等信息。

            索引节点表平时存储在磁盘上,在需要进行操作的时候读入内存,通常来说存储在磁盘上的索引节点表称作磁盘索引节点,而把其在内存中的映像称作内存索引节点表。

            索引节点表由如字段构成:

    文件类型:Linux的文件可以分为普通文件、目录文件、链接文件、设备文件、管道文件等。文件链接数:记录了引用该文件的目录表项数,即记录了有多少个文件名指向该文件。文件属主标志:指出该文件的所有者id。文件属主的组标识:指出该文件所有者属组的id。文件的访问权限:系统将用户分为文件属主、同组用户和其他用户三类,每类用户可能获得对文件中的一种或几种访问权限。需要特别指出的是,目录文件的执行权限是指修改目录的权力。文件的存取时间:包括文件最后一次被修改的时间、最后一次被访问的时间和最后一次修改索引节点的时间。文件的长度:以字节表示的文件长度。文件的数据块指针:文件操作的当前位置指针。

           在索引节点表中并不包含文件的名称,文件名的信息是存放在目录文件中。

           在Linux中的stat.h头文件中使用了一个结构体来定义索引节点表的相应字段,对其说明如下:

    #ifndef _ALPHA_STAT_H #define _ALPHA_STAT_H // 32位的索引节点表的字段结构体定义 struct stat{ unsigned int st_dev; // 文件所在位置的设备号 unsigned int st_int; // 文件的索引节点号 unsigned int st_mode; // 文件的类型 unsigned int st_nlink; // 连接到该文件的其他文件数量 unsigned int st_uid; // 文件所属用户 unsigned int st_gid; // 文件所属用户所在组 unsigned int st_rdev; // 如果是设备文件,则保存设备号,否则无效 long st_size; // 文件长度,如果是设备文件则为0 unsigned long st_atime; // 最近一次访问文件的时间 unsigned long st_mtime; // 最近的修改文件时间 unsigned long st_ctime; // 最近一次对文件状态进行修改的时间 unsigned long st_blksize;// 文件系统的块大小 unsigned long st_blocks; // 文件所分配的块数 unsigned long st_flags; // 文件的用户定义标志 unsigned long st_gen; // 文件产生编号 }; // 以下是64位系统的一些关于索引节点表的定义,增加和修改了一些项 struct stat64{ unsigned long st_dev; unsigned long st_in0; unsigned long st_rdev; unsigned int st_mode; long st_size; unsigned long st_blocks; unsigned int st_uid; unsigned int st_gid; unsigned int st_blksize; unsigned int st_nlink; unsigned int _pad0; unsigned long st_atime; unsigned long st_atime_nsec; unsigned long st_mtime; unsigned long st_mtime_sec; unsigned long st_ctime; unsigned long st_ctime_sec; long _unused[3]; }; #endif

     

    三、Linux文件属性的操作方法

            使用stat.h头文件中的stat、fstat和lstat函数来获得文件的属性结构体,如果获取成功则返回0,否则返回-1.

            对stat、fstat和lstat函数的标准调用格式说明如下:       

    #include <sys/types.h> #include <sys/stat.h> int stat(const char *pathname, struct stat *sbuf); int fstat(int fd, struct stat *sbuf); int lstat(const char *pathname, struct stat *sbuf);

           stat函数和lstat函数使用文件的路径作为参数来标识需要获取文件类型的文件,而fstat函数使用文件对应的描述符来标识需要获取类型的文件;

           lstat函数和stat函数的区别在于如果目标文件是一个符号文件,则lstat返回的是该符号链接的有关信息,而stat返回的是符号链接所引用的文件信息。

            pathname:目标文件的路径,可以是绝对路径或者相对路径,在stat和lstat函数中使用        fd:目标文件的文件描述符,通常由其他函数返回,在fstat函数中使用        sbuf:指向存放目标文件状态

    例一:使用stat函数获得指定文件的属性

            本案例中是一个使用stat函数来获得argv指定文件类型的实例,代码首先使用stat函数获取argv指定文件的属性参数,并且将其放入stat_buf结构体中,使用屏蔽码S_IFMT对st_mode中的文件类型进行屏蔽后再用switch语句对屏蔽结果进行判断,然后输出相应的结果。

    // 这是使用stat函数来获得argv指定文件类型的实例 // 应用代码首先使用stat函数获得argv制定文件的属性参数,并且将其放入stat_buf结构体中 // 使用屏蔽码S_IFMT对st_mode中的文件类型进行屏蔽后再用switch语句对屏蔽结果进行判断 // 最后输出相应的结构 #include <stdio.h> #include <sys/stat.h> #include <unistd.h> #include <stdlib.h> int main(int argc, char *argv[]){ // 创建临时变量,用来记录lstat函数的返回值 int df; // 创建stat结构体指针,用来指向stat的返回值 struct stat stat_buf; if(argc != 2){ printf("Please input the current para!\n"); return -1; } // 使用lstat函数获取文件的符号链接 df = stat(argv[1], &stat_buf); if(df == -1){ printf("获取文件属性失败!\n"); return -2; } // 使用屏蔽码S_IFMT对st_mode中的文件类型进行判断 switch(stat_buf.st_mode & S_IFMT){ case S_IFDIR: printf("该文件为目录文件!\n"); break; case S_IFREG: printf("该文件为普通文件!\n"); break; default: printf("该文件为其他类型!\n"); break; } return 0; }

            进行编译链接,生成可执行文件。分别对目录文件和普通文件进行判断,结果如下:


    参考文献:程国钢, 张玉兰. Linux C编程从基础到实践, 清华大学出版社, 2015. 

    Processed: 0.014, SQL: 8