专题2 文件系统结构

本文介绍了Unix文件系统的结构组成,包括引导块、超级块、i结点块和数据区的功能及组织方式。此外,还提供了使用C语言获取文件属性和文件系统信息的示例代码。

1.       概述

Unix文件系统可划分为引导块、超级块、i结点块(inode区)和数据区等四个部分,其中:

(1)       引导块位于文件系统的第0号物理块,它保存了文件系统的引导代码;

(2)       超级块位于文件系统的第1号物理块,它描述了文件系统本身的结构信息,这个信息的数据结构一般为“struct filsys”, 定义在文件“filsys”中;

(3)       I节点区位于超级块之后,它描述了文件的属性信息,这个信息的数据结构一般为“struct dinode”,定义在文件“ino.h”中;

(4)       数据区位于i节点之后,用于存储文件的内容。

文件系统决定了文件的存储与寻址方式,UNIX文件系统采取了3级缓冲结构,并将文件属性存储于i节点中。

UNIX下的文件属性包括文件类型、文件访问权限、文件属主ID、文件属组ID、文件链接类、文件长度和文件时间等信息,文件按类型可以分为普通文件、目录文件、管道文件、设备文件、符号链接文件和SOCKET文件等,这些信息存储在文件对应的i节点中。

UNIX下获取文件系统信息的函数有statfsfstatfs

UNIX下获取文件属性的函数有statfstatlstat

 

磁盘文件读取工作原理:以命令”cat T1.c”为例

  1. 在当前目录文件中查找文件“T1.c”及其对应的i节点编写,假设为1109
  2. i节点表中读取第1109号节点。
  3. 读取i节点中文件属性、访问权限等信息
  4. 读取i节点中磁盘地址表,按照三级索引规则在数据区读取文件内容。

2.       获取文件属性的C程序代码

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#include <sys/types.h>

#include <sys/stat.h>

#include <time.h>

 

int GetFileType(mode_t st_mode, char *resp);/*获取文件类型*/

int GetFileMode(mode_t st_mode, char *resp);/*获取文件权限*/

int GetFileOtherAttr(struct stat info, char *resp);/*获取文件其他的一些信息*/

 

int main(int argc, char *argv[])

{

    struct stat info;

    char buf[100], *p = buf;

    if(argc != 2)

    {

        fprintf(stderr, "ls1 filename/n");

        return -1;

    }

    memset(buf, 0, sizeof(buf));

    if(lstat(argv[1], &info) == 0)

    {

        p += GetFileType(info.st_mode, p);

        p += GetFileMode(info.st_mode, p);

        p += GetFileOtherAttr(info, p);

        printf("%s %s/n", buf, argv[1]);

    }

    else

    {

        fprintf(stderr, "open file failed. /n");

        return -1;

    }

    return 0;

}

 

int GetFileType(mode_t st_mode, char *resp)

{

    if(resp == NULL)

        return 0;

    if(S_ISDIR(st_mode)) /*测试是否为目录文件*/

        resp[0] = 'd';

    else if(S_ISCHR(st_mode))/*测试是否为字符文件*/

        resp[0] = 'c';

    else if(S_ISBLK(st_mode))/*测试是否为块文件*/

        resp[0] = 'c';

    else if(S_ISREG(st_mode))/*测试是否为普通文件*/

        resp[0] = '-';

    else if(S_ISFIFO(st_mode))/*测试是否为管道文件*/

        resp[0] = 'p';

    else if(S_ISLNK(st_mode))/*测试是否为符号链接文件*/

        resp[0] = '1';

    else

        resp[0] = ' ';

   

    return 1;

 

}

 

int GetFileMode(mode_t st_mode, char *resp)

{

    if(resp == NULL)

        return 0;

    memset(resp, '-', 9);

    if(st_mode & S_IRUSR) /*测试属主读权限*/

        resp[0] = 'r';

    if(st_mode & S_IWUSR)/*测试属主写权限*/

        resp[1] = 'w';

    if(st_mode & S_IXUSR)/*测试属主执行权限*/

        resp[2] = 'x';

    if(st_mode & S_IRGRP)/*测试组读权限*/

        resp[3] = 'r';

    if(st_mode & S_IWGRP)/*测试组写权限*/

        resp[4] = 'w';

    if(st_mode & S_IXGRP)/*测试组执行权限*/

        resp[5] = 'x';

    if(st_mode & S_IROTH)/*测试其他用户读权限*/

        resp[6] = 'r';

    if(st_mode & S_IWOTH)/*测试其他用户写权限*/

        resp[7] = 'w';

    if(st_mode & S_IXOTH)/*测试其他用户执行权限*/

        resp[8] = 'x';

    return 9;

}

 

int GetFileOtherAttr(struct stat info, char *resp)

{

    struct tm *mtime;

    if(resp == NULL)

        return 0;

    mtime = localtime(&info.st_mtime);

    return sprintf(resp, " %3d %6d %11d %04d%02d%02d", info.st_nlink, info.st_uid, info.st_gid, info.st_size, mtime->tm_year + 1900, mtime->tm_mon + 1, mtime->tm_mday);

}

 

3.       读取文件系统信息C程序代码

 

#include <stdio.h>

#include <stdlib.h>

#include <unistd.h>

#include <sys/types.h>

#include <sys/statfs.h>

#include <sys/vfs.h>

 

int main(int argc, char *argv[])

{

    struct statfs buf;

    if(argc != 2)

        return 1;

    statfs(argv[1], &buf);

    printf("FILE SYSTEM:/ntype=%d/n", buf.f_type);/*文件系统类型*/

    printf("bsize=%d/n", buf.f_bsize);              /*数据块大小*/

    printf("blocks=%d/n", buf.f_blocks);            /*数据块总数*/

    printf("bfree=%d/n", buf.f_bfree);              /*可用块*/

    printf("files=%d/n", buf.f_files);              /*inode总数*/

    printf("ffree=%d/n", buf.f_ffree);              /*可用inode*/

    printf("%s  : %d blocks %d i -nodes/n", argv[1], buf.f_bfree, buf.f_ffree);

    return 0;

}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值