『Others』遍历目录下的所有文件

最近在做一些文件查找相关的工具,所以需要用到遍历目录下的文件,本篇博客主要介绍如何使用C++遍历一个目录下的所有文件(包括目录和文件)

_finddata_t结构体

_finddata_t是一个用来存储文件各种信息的结构体,包含在头文件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文件属性的存储位置。它存储一个unsigned单元,用于表示文件的属性。
    文件属性是用位来表示的主要有_A_ARCH(存档)_A_HIDDEN(隐藏)_A_NORMAL(正常)_A_RDONLY(只读)_A_SUBDIR(文件夹)_A_SYSTEM(系统)
    这些都是在头文件中定义的宏,可以直接使用,而本身的意义其实是一个无符号整型(只不过这个整型应该是2的几次幂,从而保证只有一位为1,而其他位为0)。既然是位表示,那么当一个文件有多个属性时,它可以通过位或的方式,来得到几个属性的综合。例如只读+隐藏+系统属性_A_HIDDEN | _A_RDONLY | _A_SYSTEM
  • time_t time_create:这里的time_t是一个变量类型,不用去细究它,我们只需要直到time_create变量是用来存储文件创建时间的就可以了。
  • time_t time_access:文件最后一次被访问的时间
  • time_t time_write:文件最后一次被修改的时间
  • _fsize size文件的大小。这里的_fsize应该可以相当于unsigned整型,表示文件的字节数。
  • char name[_MAX_FNAME]文件的文件名这里的_MAX_FNAME是一个常量宏,它在头文件中被定义,表示的是文件名的最大长度

介绍了_finddata_t结构体,下面介绍一下三个和它搭配使用的接口

三个主要接口

_findfirst

功能搜索与指定的文件名称匹配的第一个实例

long _findfirst(char* filespec, struct _finddata_t* fileinfo);
参数:
	filespec:标明文件的字符串,可支持通配符。
	fileinfo:用来存放文件信息的结构体的指针。
返回值:
	查找成功,返回一个long型的唯一的查找用的句柄。失败返回-1

注意

  • filespec支持通配符,比如:*.c,则表示当前文件夹下的所有后缀为c的文件
  • fileinfo:这里就是用来存放文件信息的结构体的指针。这个结构体必须在调用次函数前声明,不过不用初始化只要分配了内存空间就可以了。函数成功后,函数会把找到的文件的信息放入这个结构体所分配的内存空间中
  • 返回值查找成功的句柄会在_findnext函数中被使用

_findnext

功能搜索与_findfirst函数提供的文件名称匹配的下一个实例

int _findnext(long handle, struct _finddata_t* fileinfo);
参数:
	handle:句柄,由_findfirst函数返回的句柄。
	fileinfo:用来存放文件信息的结构体指针。
返回值:
	成功返回0,失败返回-1

_findclose

功能结束查找

int _findclose(long handle);
参数:
	handle:_findfirst返回的句柄。
返回值:
	成功返回0,失败返回-1

示例

先来看一下要遍历的目录
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

#include <iostream>
#include <string>
#include <vector>
#include <io.h>
#include <stdlib.h>

using std::cout;
using std::endl;

void listDir(const std::string& path, std::vector<std::string>& subfiles,
	std::vector<std::string>& subdirs){
	_finddata_t file;

	// 使用通配符
	std::string path_ = path + "\\*.*";

	intptr_t handle = _findfirst(path_.c_str(), &file);
	if (handle == -1){
		cout << "_findfirst error" << endl;
	}

	do {
		// 判断file是否是目录文件
		if (file.attrib & _A_SUBDIR){
			// 判断file是否是.或..
			if ((strcmp(file.name, ".") != 0) && (strcmp(file.name, "..") != 0)){
				subdirs.push_back(file.name);
			}
		}
		else{
			subfiles.push_back(file.name);
		}
	} while (_findnext(handle, &file) == 0);

	// 结束查找
	_findclose(handle);
}

void listDirTest(){
	std::vector<std::string> subdirs;
	std::vector<std::string> subfiles;

	// 要遍历的目录
	std::string path = "C:\\Users\\Administrator\\Desktop\\CSDN";

	listDir(path, subfiles, subdirs);

	// 打印目录下的文件
	cout << "files: " << subfiles.size() << endl;
	for (size_t i = 0; i < subfiles.size(); ++i){
		cout << subfiles[i] << endl;
	}
	cout << endl;

	// 打印目录下的目录文件
	cout << "dirs: " << subdirs.size() << endl;
	for (size_t i = 0; i < subdirs.size(); ++i){
		cout << subdirs[i] << endl;
	}
}

int main(){

	listDirTest();
	
	system("pause");
	return 0;
}

在这里插入图片描述
从上述结果,我们注意到,该程序只能遍历一个目录下的所有文件,而不会去遍历目录下的目录文件中的文件,下面我们来完善一下程序,可以遍历一个目录下的所有文件,包括文件下的目录文件中的文件。

递归遍历目录下所有文件

#include <iostream>
#include <string>
#include <vector>
#include <io.h>
#include <stdlib.h>

using std::cout;
using std::endl;

void listDir(const std::string& path, std::vector<std::string>& subfiles,
	std::vector<std::string>& subdirs){
	_finddata_t file;

	// 使用通配符
	std::string path_ = path + "\\*.*";

	intptr_t handle = _findfirst(path_.c_str(), &file);
	if (handle == -1){
		cout << "_findfirst error" << endl;
	}

	do {
		// 判断file是否是目录文件
		if (file.attrib & _A_SUBDIR){
			// 判断file是否是.或..
			if ((strcmp(file.name, ".") != 0) && (strcmp(file.name, "..") != 0)){
				subdirs.push_back(path + "\\" + file.name);
			}
		}
		else{
			subfiles.push_back(path + "\\" + file.name);
		}
	} while (_findnext(handle, &file) == 0);

	// 结束查找
	_findclose(handle);
}

void listDirTest(){
	std::vector<std::string> subdirs;
	std::vector<std::string> subfiles;

	// 要遍历的目录
	std::string path = "C:\\Users\\Administrator\\Desktop\\CSDN";

	// 遍历目录
	listDir(path, subfiles, subdirs);

	// 递归遍历子目录
	for (size_t i = 0; i < subdirs.size(); ++i){
		listDir(subdirs[i], subfiles, subdirs);
	}

	// 打印目录下的文件
	cout << "files: " << subfiles.size() << endl;
	for (size_t i = 0; i < subfiles.size(); ++i){
		cout << subfiles[i] << endl;
	}
	cout << endl;

	// 打印目录下的目录文件
	cout << "dirs: " << subdirs.size() << endl;
	for (size_t i = 0; i < subdirs.size(); ++i){
		cout << subdirs[i] << endl;
	}
}

int main(){

	listDirTest();
	
	system("pause");
	return 0;
}

在这里插入图片描述

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值