0
点赞
收藏
分享

微信扫一扫

文件系统-目录和文件2

拾光的Shelly 2022-03-12 阅读 122
linuxc语言

11.分析目录/读取目录内容

glob(): 解析模式/通配符

1.能够实现下面函数所有操作
在这里插入图片描述
作用:帮忙分析pattern(通配符)
参数详解:
pattern: 模式或通配符
flags:以按位或的形式把0个或多个符号信息或进参数flag里
在这里插入图片描述
常用符号信息:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
int (*errfunc) (const char *epath, int eerrno):
保存当前出错的路径和原因
glob_t *pglob: 将解析pattern的结果存放到glob_t指针指向的地址中去
在这里插入图片描述
(gl_pathc, *gl_pathv)和(argc, 、 argv)组合非常相近
(argc, 、
*argv)组合结构:
在这里插入图片描述

globfree函数:

opendir()
closedir()
readdir()
rewinddir()
seekdir()
telldir()

使用glob函数实现du命令功能
在这里插入图片描述
在这里插入图片描述

$:du
显示当前路径占的空间大小,默认以字节为单位显示
$:du filename
表示文件占的磁盘大小
$du filename1 filename2 ...
分别显示多个文件占的磁盘大小

思路:
1.如果du后面为空,则对当前目录进行操作;
2.如果du后面有路径信息,则对给定的路径进行解析。
路径分为两种,一种是非目录文件,一种是目录文件。
对于非目录文件,直接计算block
对于目录文件,把目录文件使用glob进行路径解析,使用递归计算

//FS/mydu.c
//避免回路,陷入递归死循环
static int pathnoloop(const char* path)
{
	char *pos;
	
	pos = strrchr(path, '/');
	if(pos == NULL)
		exit(1);
	if(strcmp(pos+1, ".") == 0 || strcmp(pos+1, "..") == 0)
		return 0;
	
	return 1;
}

static int64_t mydu(const char* path)
{
	//1.struct stat buf; 调整后,buf只在递归之前出现,则可以优化到静态区
	static struct stat buf;
	static char nextpath[PATHSIZE]; //只在递归前出现,可以优化
	glob_t globres;
	int i; //不可优化,跨递归
	int64_t sum;

	if(lstat(path, &buf) < 0)
	{
		perror("lstat()");		
		exit(1);
	}
	
	if(!S_ISDIR(buf.st_mode))
	{
		return buf.st_blocks;
	}

	//	/aaa/bbb/ccc/ddd/eee/*
	//  /aaa/.*
	strncpy(nextpath, path, PATHSIZE);
	strncat(nextpath, "/*", PATHSIZE);
	glob(nextpath, 0, NULL, &globres);	
		
	strncpy(nextpath, path, PATHSIZE);
	strncat(nextpath, "/.*", PATHSIZE);
	glob(nextpath, GLOB_APPEND, NULL, &globres);

	//1.sum = 0;
	sum = buf.st_blocks;
	for(i = 0; i < globres.gl_pathc; i++)
	{
		if(pathnoloop(globres.gl_pathv[i])) 
			sum += mydu(globres.gl_pathv[i]);
	}
	//1.增加当前路径的大小	
	//sum += buf.st_blocks;
	globfree(&globres);
	return sum; 
} 

小结
1.如何在栈不破裂的情况下,增加递归的层数?
压一个现场,需要压返回地址,局部变量,函数递归传递的参数
返回地址、参数不可省,局部变量可以通过其他方式减少。进而减少一个现场传递的内容,提高递归层数。
建议:
如果一个变量的使用单纯的在递归点之前(之后),则这个变量可以被优化到静态区存放。
如果一个变量的使用跨了递归区间,则不能优化;

举报

相关推荐

0 条评论