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下获取文件系统信息的函数有statfs和fstatfs。
UNIX下获取文件属性的函数有stat、fstat和lstat。
磁盘文件读取工作原理:以命令”cat T1.c”为例
在当前目录文件中查找文件“T1.c”及其对应的i节点编写,假设为1109。在i节点表中读取第1109号节点。读取i节点中文件属性、访问权限等信息读取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, " = m d ddd", 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;
}