遍历文件可以用 _findfirst, _findnext, _findclose
long _findfirst( char *filespec, struct _finddata_t *fileinfo );
返回值:
如果查找成功的话,将返回一个long型的唯一的查找用的句柄。这个句柄将在_findnext函数中被使用。若失败,则返回-1。
参数:
filespec:标明文件的字符串,可支持通配符。
fileinfo :这里就是用来存放文件信息的结构体的指针。
函数成功后,函数会把找到的文件的信息放入这个结构体中。
int _findnext( long handle, struct _finddata_t *fileinfo );
返回值:
若成功返回0,否则返回-1。
参数:
handle:即由_findfirst函数返回回来的句柄。
fileinfo:文件信息结构体的指针。
int _findclose( long handle );
返回值:成功返回0,失败返回-1。
参数: handle :_findfirst函数返回回来的句柄。
用到的结构体 struct _finddata_t 定义如下
struct _finddata64i32_t
{
unsigned attrib; // 文件属性
__time64_t time_create; // -1 for FAT file systems 创建文件时间
__time64_t time_access; // -1 for FAT file systems 最后访问时间
__time64_t time_write; // 最后修改时间
_fsize_t size; // 文件大小
char name[260]; // 文件名
};
流程就是 通过_findfirst获取一个句柄,然后通过_findnext挨个获取文件,类似单向链表的遍历过程
直接上代码
#include
#include
#include
#include
#include
#include
int file_list(const char *path)
{
char file[MAX_PATH] = "";
sprintf_s(file, MAX_PATH, "%s\\*", path);
long handle;
struct _finddata_t fileinfo;
handle = _findfirst(file, &fileinfo);
if (-1 == handle) {
return -1;
}
if (!(fileinfo.attrib & _A_SUBDIR))
{
char file[MAX_PATH] = "";
sprintf_s(file, MAX_PATH, "%s\\%s", path, fileinfo.name);
printf("[%s]\n", file);
}
while (!_findnext(handle, &fileinfo))
{
// 去除.和..,如果是文件夹,就递归遍历
if (strcmp(fileinfo.name, ".") != 0 && strcmp(fileinfo.name, "..") != 0 && (fileinfo.attrib&_A_SUBDIR))
{
char dir[MAX_PATH] = "";
sprintf_s(dir, MAX_PATH, "%s\\%s", path, fileinfo.name);
file_list(dir);
}
/*
#define _A_NORMAL 0x00 // Normal file - No read/write restrictions
#define _A_RDONLY 0x01 // Read only file
#define _A_HIDDEN 0x02 // Hidden file
#define _A_SYSTEM 0x04 // System file
#define _A_SUBDIR 0x10 // Subdirectory
#define _A_ARCH 0x20 // Archive file
*/
// 不是文件夹,就输出文件名
if (!(fileinfo.attrib & _A_SUBDIR))
{
char file[MAX_PATH] = "";
sprintf_s(file, MAX_PATH, "%s\\%s", path, fileinfo.name);
printf("[%s]\n", file);
}
}
_findclose(handle);
return 0;
}
// 获取当前系统的磁盘盘符
char *get_disk_volume()
{
char *volume = (char *)malloc(sizeof(char) * 26);
DWORD drive = GetLogicalDrives();
unsigned int i = 0;
unsigned int j = 0;
for (i = 0; i < 26; i++)
{
if (drive & (1 << i))
{
volume[j++] = i + 'A';
}
}
volume[j] = '\0';
return volume;
}
// 获取当前系统的磁盘盘符
char *get_disk_volume2()
{
char *volume = (char *)malloc(26);
unsigned int i = 0;
char buff[1024] = "";
DWORD len = 26 * 4;
len = GetLogicalDriveStringsA(len, buff);
for (i = 0; i < len / 4; i++)
{
volume[i] = buff[4 * i];
}
volume[i] = '\0';
return volume;
}
int main(int argc, char *argv[]) {
DWORD starttime = GetTickCount();
char *volume = get_disk_volume();
for (unsigned int i = 0; i < strlen(volume); i++)
{
char drive[3] = "";
sprintf_s(drive, 3, "%c:", volume[i]);
file_list(drive);
}
free(volume);
printf("search time=[%f] seconds\n", (GetTickCount() - starttime) / 1000.0f);
system("pause");
return 0;
}
最后的结果大概是这样
系统文件比较多,花了83秒多才遍历完
用这一套东西,也可以查找文件,代码也许类似这样
// 查到返回true,查不到返回false
bool find_file(const char *path, const char *filename)
{
bool bret = false;
char file[MAX_PATH] = "";
sprintf_s(file, MAX_PATH, "%s\\*", path);
long handle;
struct _finddata_t fileinfo;
handle = _findfirst(file, &fileinfo);
if (-1 == handle) {
return false;
}
if (strcmp(fileinfo.name, filename) == 0)
{
char name[MAX_PATH] = "";
sprintf_s(name, MAX_PATH, "%s\\%s", path, fileinfo.name);
printf("[%s]\n", name);
bret = true;
}
while (!_findnext(handle, &fileinfo))
{
if (strcmp(fileinfo.name, ".") != 0 && strcmp(fileinfo.name, "..") != 0 && (fileinfo.attrib&_A_SUBDIR))
{
char dir[MAX_PATH] = "";
sprintf_s(dir, MAX_PATH, "%s\\%s", path, fileinfo.name);
// 这里可以做路径过滤,比如C:\Windows一些系统目录也许就不用查了
// C盘只查 C:\\Program Files和 C:\Program Files (x86)
if (path[0] == 'C' && strncmp(dir, "C:\\Program Files", 16) != 0)
{
continue;
}
if (find_file(dir, filename))
{
bret = true;
}
}
if (strcmp(fileinfo.name, filename) == 0)
{
char name[MAX_PATH] = "";
sprintf_s(name, MAX_PATH, "%s\\%s", path, fileinfo.name);
printf("[%s]\n", name);
bret = true;
}
}
_findclose(handle);
return bret;
}
这样调用,find_file(drive, "iexplore.exe");如果需要查找所有word文档,第二个参数可以传入*.doc
输出结果是这样