第4章 文件系统:编写pwd

1.从用户角度看文件系统

从用户角度看unix系统中硬盘上的文件组成一棵目录树,每个目录能包含文件或其他目录。

du(disk usage 的简称)是用于查找文件和目录的磁盘使用情况的命令,df(disk filesystem 的简称)用于显示 Linux 系统的磁盘利用率。

2.unix文件系统的内部结构

第一层抽象:从磁盘到分区;第二层抽象:从磁盘到块序列,为磁盘块编号;第三层抽象:从块序列到三个区域划分

文件系统中的第一个块称为超级块,这个块存放文件系统本身的结构信息;

每个文件都有一些属性,这些性质被记录在一个称为i- 节点的结构中;

文件系统的第三个部分是数据区,文件内容保存在这里。

创建一个文件的过程

(1)存储属性:内核先找到一个空的i- 节点;

(2)存储数据:内核从自由块的列表中找出自由块;

(3)记录分配情况:内核在i-节点的磁盘分布区记录了上述的块序列;

(4)添加文件名到目录:文件名和i-节点对应的文件内容和属性连接了起来。

比例创建一个新文件  who > userlist

目录是包含了文件名字列表的特殊文件,它的抽象模型是一个包含i-节点号和文件名的表,其中i-节点包含了文件的属性和数据块的列表。根目录的"."当前目录和".."父目录都指向自己。

cat命令的工作原理

(1)在目录中寻找文件名

(2)定位i-节点并读取其内容

(3)访问存储文件内容的数据块

所有从文件读取数据的命令,例如cat、cp、more、who等,都是将文件名传给open来访问文件内容。对open的每次调用都是先在目录中寻找文件名,然后根据目录中的i-节点号获取文件的属性,最终找到文件内容。

unix使用间接块存储大文件

3.理解目录

从用户角度看,目录是一个文件名的列表;从unix角度看是一个被命名的指针列表。

使用ls -iaR可以列出一棵树中的所有文件的i-节点号。

目录包含的是文件的引用,每个引用被称为链接。文件的内容存储在数据块,文件的属性被记录在i-节点中。

文件没有文件名,仅拥有i-节点号,但是链接具有名字。

unix使用mkdir、rmdir、mv(rename)、ln(link)、cd(chdir)和rm(unlink)等命令对树状目录结构进行管理。

4.编写pwd

(1)得到“.”的i-节点号,称其为n(使用stat)

(2)chdir .. (使用chdir)

(3)找到i-节点号n链接的名字(使用opendir、readdir、closedir)

重复直到到达树的顶端

pwd命令重复循环直到一个目录的“.”和“..”的i-节点号相同时,就可以认为已经到达文件树的顶端。

建立一个循环,使用strcat或sprintf建立目录名字的字符串序列。通过一个递归的程序逐步到达树的顶端来一个接一个地显示目录名,从而避免了字符串的管理。

/* spwd.c: a simplified version of pwd
 *
 *	starts in current directory and recursively
 *	climbs up to root of filesystem, prints top part
 *	then prints current part
 *
 *	uses readdir() to get info about each thing
 *
 *      bug: prints an empty string if run from "/"
 **/
#include<stdio.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<dirent.h>
#include<stdlib.h>
#include<string.h>

ino_t	get_inode(char *);
void    printpathto(ino_t);
void    inum_to_name(ino_t , char *, int );

int main()
{
	printpathto( get_inode( "." ) );	/* print path to here	*/
	putchar('\n');				/* then add newline	*/
	return 0;
}

void printpathto( ino_t this_inode )
/*
 *	prints path leading down to an object with this inode
 *	kindof recursive
 */
{
	ino_t	my_inode ;
	char	its_name[BUFSIZ];

	if ( get_inode("..") != this_inode )
	{
		chdir( ".." );				/* up one dir	*/

		inum_to_name(this_inode,its_name,BUFSIZ);/* get its name*/

		my_inode = get_inode( "." );		/* print head	*/
		printpathto( my_inode );		/* recursively	*/
		printf("/%s", its_name );		/* now print	*/
							/* name of this	*/
	}
}

void inum_to_name(ino_t inode_to_find , char *namebuf, int buflen)
/*
 *	looks through current directory for a file with this inode
 *	number and copies its name into namebuf
 */
{
	DIR		*dir_ptr;		/* the directory */
	struct dirent	*direntp;		/* each entry	 */

	dir_ptr = opendir( "." );
	if ( dir_ptr == NULL ){
		perror( "." );
		exit(1);
	}

	/*
	 * search directory for a file with specified inum
	 */

	while ( ( direntp = readdir( dir_ptr ) ) != NULL )
		if ( direntp->d_ino == inode_to_find )
		{
			strncpy( namebuf, direntp->d_name, buflen);
			namebuf[buflen-1] = '\0';   /* just in case */
			closedir( dir_ptr );
			return;
		}
	fprintf(stderr, "error looking for inum %ld\n", inode_to_find);
	exit(1);
}

ino_t get_inode( char *fname )
/*
 *	returns inode number of the file
 */
{
	struct stat info;

	if ( stat( fname , &info ) == -1 ){
		fprintf(stderr, "Cannot stat ");
		perror(fname);
		exit(1);
	}
	return info.st_ino;
}

多文件系统的组合:由多棵构成的树。unix允许将一个磁盘的存储组织成一棵由多棵树相互连接的树,每个磁盘或磁盘上的每个分区都包含一棵目录树,unix提供一种方法将这些树整合成一棵更大的树。

5.符号链接

硬链接是将目录链接到树的指针,硬链接同时也是将文件名和文件本身链接起来的指针,原文件和硬链接i-节点相同,文件属性也相同,删除原文件硬链接无影响。创建硬链接使用ln命令

软链接通过名字引用文件,和原文件的i-节点号不同,相当于原文件的快捷方式,删除原文件,软连接失效。创建软连接ln -s

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值