文件系统

本文介绍UNIX文件系统的结构,包括分区的组成、超级块的作用及inode的概念,并提供了读取分区信息和列出目录下文件inode号的示例程序。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

转载自http://club.it.sohu.com/read_elite.php?b=program&a=186956


本文所有程序均应在UNIX系操作系统下编译执行。

第四章:文件系统

UNIX所管理的机器一般是大型机而不是PC。所管理的硬盘一般也非常大。所以一般分成几个区,每个区都有其单独的文件系统。比方说你能大概能找到这样的一些文件
/dev/sd/c0t0d0s0
/dev/sd/c0t0d0s1
... ...
当UNIX启动的时候,分区被挂装(mount)并统一成一个树状的文件系统
分区的物理构造咱们暂且放在一边,先写个程序,读一下分区信息试试。

/* ndf.c 计算参数所指定的分区的剩余空间比率 */
#include
#include
#include

int main(int argc , char *argv[])
{
struct statvfs buf[1];
sync();
if( statvfs(argv[1],buf)!=0 )
{
fprintf(stderr , Cannot read super block !\n);
exit(1);
}
fprintf(stderr , %4.1f %% free\n,
(float)buf[0].f_bfree / buf[0].f_blocks*100 );
return 0;
}

编译执行:
%./ndf /
49.8 % free

这里用了一个statvfs函数。其具体如下:
#include
#include
int statvfs( char *path , struct statvfs *buf );
返回值: 成功时: 0
失败时: -1
还有一个sync()函数。用来更新分区的super block;
void sync();
UNIX系统为了加快处理速度,将分区的super block信息读到内存中保存。sync()函数就是把在内存中保存的super block信息再写回到硬盘上去。

UNIX系统使用好几种文件系统。有S5,ufs,VxFS等等。虽然这些文件系统的构造非常不同,但一通百通,咱们在这几篇贴子里只讨论一下比较容易理解,而且“经典的”S5文件系统。(别的我也不会。呵呵)
S5: 文件名最长14字节,构造简单
ufs: 文件名最长255字节,BSD所用的文件系统。
VxFS: Veritas Softwave公司开发的文件系统。出现错误时可以快速恢复。由于这种文件系统保证文件在硬盘上连续存放,所以处理速度很快。

现在说一下S5分区的构造
一个分区包含如下四部分(按顺序):
[ boot block ]
[ super block ]
[ i node block ]
[ data block ]

boot block :
这个部分在分区的最开始处,用来存放引导程序。就算是不能引导的分区一样有boot block,这个时候这部分就没有用了。不过一般这部分也不大。大多数只有512或者1024字节。
super block :
super block在boot block之后,用来存放这个分区全体的管理信息。上面那个ndf.c就是读的这部分所存储的信息。里边存放了i node block的大小,free block数组等等。根据这些信息可以得知data block的开始位置。
i node block :
i node是index node的缩写。i node block就是存放i node的部分
UNIX把一切都看成是个文件。包括目录以及设备等等的所有的文件都有一个i node号,作为这个文件的管理信息。文件本身存在于数据区,但是i node号存在i node block里。主要包含文件的模式,链接数,文件所有者,文件大小,在硬盘上的位置,最后读写时间,最后更新时间等信息。
为了加快存储速度,系统会把一定数量的i node存至内存。UNIX系统不一样,存多少也就不一样。
data block :
这部分就是存放数据本身的了。这部分被分成一定大小的块,如同DOS的扇区一样。一般大小是1024字节,分到4096的也有。

解说到这里,我们再来写个程序。打开一个目录,然后把这个目录下所有的文件的i node号及文件名输出来。

/* nls.c */
#include
#define DIRSIZ 14
int main( int argc , char *argv[] )
{
struct dir
{
int i_no;
char f_name;
};
struct dir dir_data[1];
FILE *fp;
fp=fopen(argv[1],r);
while( fscanf(fp,%i%s,&(dir_data[0].i_no),dir_data[0].f_name)!=EOF )
{
printf(%i %s\n , dir_data[0].i_no , dir_data[0].f_name );
}
fclose(fp);
return 0;
}

%./nls /
... ...
2048 usr
2049 home
... ...

别忘了,在UNIX下,目录也当成文件。
最近,为了使目录的格式变得通用而不再依赖于操作系统,程序中大多使用统一的格式。这种情况下,我们最好就不直接用fopen()打开目录,而使用opendir(),readdir()等函数比较好。重写一下上面的程序。

/* nls2.c */
#include
#include
int main( int argc , char *argv[] )
{
DIR *fp;
struct dirent *p;
fp=opendir(argv[1]);
while( (p=readdir(fp))!=NULL )
{
printf(%i %s\n, p->d_ino , p->d_name );
}
closedir(fp);
return 0;
}

执行结果和上面一样。函数说明如下:
#include
DIR *opendir( char *dirname ); 打开一个目录,成功时返回DIR结构体的地址,失败返回NULL
struct dirent *readdir( DIR *dirp ); 取得打开目录中下一个文件的信息,成功时返回下一个文件信息的地址,失败时,或者读至末尾时返回NULL
int closeidr( DIR *dirp ); 关闭目录,成功时返回0,失败时返回-1

注意:readdir在成功地读出一项之后,会自动指向下一项。假设你有如下程序:
struct dirent *p;
p=readdir(fp);
p++; //千万不要像这行这样写。你无法保证这目录里的文件信息是连续存放的。

你只要一遍一遍地用readir()这个函数就行了。它帮你全搞定
内容概要:该研究通过在黑龙江省某示范村进行24小时实地测试,比较了燃煤炉具与自动/手动进料生物质炉具的污染物排放特征。结果显示,生物质炉具相比燃煤炉具显著降低了PM2.5、CO和SO2的排放(自动进料分别降低41.2%、54.3%、40.0%;手动进料降低35.3%、22.1%、20.0%),但NOx排放未降低甚至有所增加。研究还发现,经济性和便利性是影响生物质炉具推广的重要因素。该研究不仅提供了实际排放数据支持,还通过Python代码详细复现了排放特征比较、减排效果计算和结果可视化,进一步探讨了燃料性质、动态排放特征、碳平衡计算以及政策建议。 适合人群:从事环境科学研究的学者、政府环保部门工作人员、能源政策制定者、关注农村能源转型的社会人士。 使用场景及目标:①评估生物质炉具在农村地区的推广潜力;②为政策制定者提供科学依据,优化补贴政策;③帮助研究人员深入了解生物质炉具的排放特征和技术改进方向;④为企业研发更高效的生物质炉具提供参考。 其他说明:该研究通过大量数据分析和模拟,揭示了生物质炉具在实际应用中的优点和挑战,特别是NOx排放增加的问题。研究还提出了多项具体的技术改进方向和政策建议,如优化进料方式、提高热效率、建设本地颗粒厂等,为生物质炉具的广泛推广提供了可行路径。此外,研究还开发了一个智能政策建议生成系统,可以根据不同地区的特征定制化生成政策建议,为农村能源转型提供了有力支持。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值