有序删除:先文件后目录
我们看看用程序清理下面这种文件结构时的表现。
CS.GLIMIX.COM
│ 001.png
│ format.txt
│ fun.c
│ fun.h
│ main.c
│
├─Debug
│ fun.obj
│ main.obj
│ va.obj
│ vb.obj
│
├─Release
│ main.obj
│ tutorials.exe
│ tutorials.log
│
└─test
fun.c
fun.h

目前ccleaner在删除上的逻辑是遇到什么删除什么。如果我们希望先删除文件,然后是文件夹,这就需要先将文件夹名称缓存起来,在删除完当前目录下的全部文件后,再从缓存中取出一个目录,执行文件/文件夹删除逻辑,直到所有的子目录删除完成。这里对文件名称的缓存,是通过一个指针数组来表达。
char *subdirs[BUFSIZ] = { 0 }; // 存储子文件夹名称
int sdidx = 0; // 文件夹存储位置索引
在查找文件时,我们可以通过strdup()函数,创建名称字符串副本,然后将它存储到subdirs中。
if (fd.attrib & _A_SUBDIR)
{
if (strcmp(fd.name, ".") != 0 && strcmp(fd.name, "..") != 0)
{
// 保存文件夹名称
subdirs[sdidx++] = _strdup(fd.name);
}
}
strdup先使用malloc分配空间然后复制内容,所以要记得使用free释放。
一切就绪后,我们通过遍历subdirs进行递归删除。
for (int i = 0; i < sdidx; i++)
{
char subdir[BUFSIZ];
sprintf_s(subdir, BUFSIZ, "%s\\%s", dir, subdirs[i]);
// 递归遍历子文件夹
dirctx subctx;
bool ok = clear_core(subdir, &subctx);
// 遍历完成 && 移除空文件夹 && 本次在子文件夹查找与删除的文件计数一致
if (ok && opts.remove_empty_dir && (subctx.found_count == subctx.delete_count))
{
// 在当前层删除子文件夹,成功后,文件删除计数加1
if (_rmdir(subdir) == 0)
{
ctx->delete_count += 1;
ctx->delete_dir_count += 1;
}
}
// 当前层文件计数加1(不能在删除文件夹之前累加,
// 此时subctx.delete_count统计的仅仅是已删除的文件数量,这当中不包括文件夹计数)
ctx->found_count += 1;
// 释放strdup分配的内存
free(subdirs[i]);
}
现在,我们就可以得到一个整齐的输出了。

陕公网安备61011202001108号