准备阶段
在完成这个遍历删除任务之前,我们要先完成一下准备阶段的任务。最重要的就是**_**finddata_t结构体的使用和remove()以及rmdir()函数的使用。
首先remove()函数是用来删除文件的
头文件:#include <stdio.h>
remove()函数用于删除指定的文件,其原型如下:
int remove(char * filename);成功则返回0,失败则返回-1,
这里 * filename指针是一个指向字符串常量的地址,也就是需要删除的文件名字如
“D://text//123.txt” 这就是一个我们需要操作的地址
需要注意的是remove()函数我用来删除单个的文件,当文件夹内为空时,我才用rmdir()函数来删除空的文件夹(当然也只能删除空文件夹);
接下来我们要了解一下_finddata_t结构体用法。
Struct _finddata_t是用来存储文件各种信息的结构体,使用这个结构体要引用的头文件为“ #include <io.h>”它的结构体定义如下:
struct _finddata_t
{
unsigned attrib;
time_t time_create;
time_t time_access;
time_t time_write;
_fsize_t size;
char name[_MAX_FNAME];
};
unsigned attrib:无符号整形、位表示。它的作用是表示文件的属性,一般来说,文件的属性有如下几种:
_A_ARCH(存档)、 _A_HIDDEN(隐藏)、_A_NORMAL(正常)、_A_RDONLY(只读)、_A_SUBDIR(文件夹)、_A_SYSTEM(系统)
time_t time_create:表示从1970年1月1日0时0分0秒到现在时刻的秒数。实际上就是长整形变量 long int
time_t time_access:文件最后一次被访问的时间
time_t time_write:文件最后一次被修改的时间
_fsize_t size:文件的大小。
char name[_MAX_FNAME]:文件的文件名,这里的_MAX_FNAME是一个常量宏,它在头文件中被定义,表示的是文件名的最大长度。
与这个结构体配对的函数为_findfirst、_findnext和_fineclose。
下面解释这三个函数的作用
long _findfirst( char *filespec, struct _finddata_t *fileinfo );
返回值:如果查找成功,那么就返回一个long型的唯一查找用的句柄。这个句柄会在_findnext函数中被使用。失败的话就会返回0.
参数:filespec:标明文件的字符串。例如:*.c
fileinfo:这里就是用来存放文件信息的结构体的指针。函数成功后,函数会把找到的文件的信息放入这个结构体所分配的内存空间中。
int _findnext( long handle, struct _finddata_t *fileinfo );
返回值:若成功返回0,否则返回-1。
参数:handle:即由_findfirst函数返回回来的句柄。
int _findclose( long handle );
返回值:成功返回0,失败返回-1。
该结构体和搭配的函数使用的逻辑就是先用_findfirst查找第一个文件,若成功则用返回的句柄,调用_findnext函数查找其他的文件,当查找完毕后用,用_findclose函数结束查找。
正式开始,下面为查询程序
#include<io.h>
#include <direct.h>
#include<string.h>
#include<stdio.h>
#include<stdlib.h>
void findfile(char path[], char mode[])
{
struct _finddata_t file;
long HANDLE;
char Onepath[100];
int i = 0;
strcpy(Onepath, path);
strcat(Onepath, mode);
HANDLE = _findfirst(Onepath, &file);
if (HANDLE != -1)
{
do {
//判断是否有子目录
if (file.attrib & _A_SUBDIR)//_A_SUBDIR 判断是否为文件夹
{
//判断是否为"."当前目录,".."上一层目录
if ((strcmp(file.name, ".") != 0) && (strcmp(file.name, "..") != 0))
{
char newPath[100];
strcpy(newPath, path);
strcat(strcat(newPath, "\\"), file.name);
findfile(newPath, mode);
}
}
else
{
i++;
printf("%s \n", file.name);
char Del_file_name[100];
strcpy(Del_file_name, path);
strcat(Del_file_name, "\\");
strcat(Del_file_name, file.name);
remove(Del_file_name);
rmdir(path);
}
} while (_findnext(HANDLE, &file) == 0);
}
else
{
printf("can't open the path\n");
}
_findclose(HANDLE);
printf("Find %d files\n", i);
}
int main()
{
char mode[100] = "\\*.*";
char path[100] = "D:\\text";
findfile(path, mode);
return 0;
}
为了便于在编译调试时,方便理解file.name的值,从而理解程序的执行过程,我在这附上一张cmd指令查看的目标文件的图
下面为删除程序(注意路径小心操作)(未优化)
该程序的运行方式和其他删除程序方式可能有些许不同,本程序的流程是先将一个文件夹的内容对应后缀文件删除完毕后,才进入下一个子文件夹继续删除,而一些人的流程是,遇到子文件夹便进入删除完毕后在退出,最后删除母文件夹的文件。我的流程更加符合人的操作方式,先完成一层任务后在进入下一层
匆忙完成,对一些细节还没有彻底优化操作
#include<io.h>
#include <direct.h>
#include<string.h>
#include<stdio.h>
#include<stdlib.h>
#include<iostream>
using namespace std;
void findfile(char path[], char mode[], char s_name[]);
bool judge_name(char del_name[], char judgename[]);
#include"del_file.h"
char del_filename[512];
char *p = del_filename;
char *q = p;
void findfile(char path[], char mode[], char s_name[])
{
struct _finddata_t file;
long handle;
char delpath[100];
int i = 0;
strcpy(delpath, path);
strcat(delpath, mode);
handle = _findfirst(delpath, &file);
if (handle != -1)
{
do{
if (file.attrib & _A_SUBDIR)//_a_subdir 判断是否为文件夹
{
if ((strcmp(file.name, ".")!= 0) && (strcmp(file.name, "..") != 0))
{
char newpath[100];
strcpy(newpath, path);
strcat(strcat(newpath, "\\"), file.name);
strcat(strcat(del_filename, newpath), ";");
}
}
else
{
//printf("%s \n", file.name);
char del_file_name[100];
strcpy(del_file_name, path);
strcat(strcat(del_file_name, "\\"), file.name);
cout << del_file_name << endl;
if (judge_name(del_file_name, s_name))
{
remove(del_file_name);
rmdir(path);
}
}
} while (_findnext(handle, &file) == 0);
}
else
{
printf("can't open the path\n");
}
_findclose(handle);
printf("find %d files\n", i);
while (*q != '\0')
{
char filename[50];
char *f = filename;
while (*q != ';'){ q++; }
memcpy(f, p, (q - p)*sizeof(char));
f = f + (q - p) ;
*f = '\0';
q += 1;
p = q;
cout << filename<<endl;
findfile(filename, mode, s_name);
}
}
bool judge_name(char del_name[], char judgename[])
{
int n = strlen(del_name);
char *p = del_name;
p = p + n - 1;
while (*p != '.'){ p--; }
char *f = p;
char *q = judgename;
while (*p != '\0')
{
if (*p != *q)
{
p = f;
while (*q != '.')
{
if (*q == '\0')
return false;
q++;
}
}
else
{
p++;
q++;
}
}
return true;
}
int main()
{
char mode[100] = "\\*.*";
char path[100] = "D:\\text";
char s_name[20] = ".txt.bmp.xlsx";
findfile(path, mode, s_name);
return 0;
}