Windows下,在VS中开发,C++遍历文件夹下文件。
在Windows下,遍历文件所用到的函数和结构体,需要在程序中包含头文件#include <io.h>,在VS中,头文件io.h实际上是包含了另一个头文件corecrt_io.h的,所以需要用到的函数和结构体也都是包含在corecrt_io.h这个头文件中的。
首先是遍历文件的时候用于存储文件信息的结构体_finddata_t,_finddata_t在头文件中是一个宏定义:
#define _finddata_t _finddata64i32_t
而_finddata64i32_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];
};
也就是这个结构体中包含了六个信息,文件属性(attrib),创建时间(time_create),最近访问时间(time_access)、最近写入时间(time_write)、文件大小(size)和文件名(name)。文件属性有以下几种:
#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,存档文件
之后要遍历文件夹,需要用到三个函数_findfirst、_findnext、_findclose,前两个是宏定义,指向了两个函数:
#define _findfirst _findfirst64i32
#define _findnext _findnext64i32
1、_findfirst的函数声明为:
_Success_(return != -1) _Check_return_ _ACRTIMP intptr_t __cdecl _findfirst64i32( _In_z_ char const* _FileName, _Out_ struct _finddata64i32_t* _FindData );
这个函数是查找符合条件的第一个实例,第一个参数_FileName是一个通配符,可以是”*.*”或者”xxxxx.*”,或者”xxxxxx/*”,或者”*.txt”等方式,第二个参数_FindData则是用于存储当前查找到的文件的信息。如果查找成功则返回intptr_t类型的句柄,该句柄不是指针,而是
typedef int intptr_t;
如果失败,返回-1,成功则返回句柄。
2、_findnext的函数声明为:
_Success_(return != -1) _Check_return_ _ACRTIMP int __cdecl _findnext64i32( _In_ intptr_t _FindHandle, _Out_ struct _finddata64i32_t* _FindData );
函数是查找句柄的下一个符合条件的实例,输入变量_FindHandle就是当前的句柄,_FindData则是下一个句柄的实例的文件信息,失败返回-1, 成功返回0。
3、_findclose的函数声明为:
_Check_return_opt_ _ACRTIMP int __cdecl _findclose( _In_ intptr_t _FindHandle );
则是根据句柄关闭查找,成功返回0,失败返回-1;
例子:
#include <io.h>
void getFiles(std::string path, std::vector<std::string>& files, std::vector<std::string>& names)
{
//文件句柄,win10用long long,win7用long就可以了
long hFile = 0;
//文件信息
struct _finddata_t fileinfo;
std::string p;
if ((hFile = _findfirst(p.assign(path).append("\\*").c_str(), &fileinfo)) != -1)
{
do
{
//如果是目录,迭代之 //如果不是,加入列表
if ((fileinfo.attrib & _A_SUBDIR))
{
if (strcmp(fileinfo.name, ".") != 0 && strcmp(fileinfo.name, "..") != 0)
{
getFiles(p.assign(path).append("\\").append(fileinfo.name), files, names);
}
}
else
{
files.push_back(p.assign(path).append("\\").append(fileinfo.name));
names.push_back(fileinfo.name);
}
}while (_findnext(hFile, &fileinfo) == 0);
_findclose(hFile);
}
}
觉来窗牖空,寥落雨声晓。
良游怨迟暮,末事惊纷扰。
为问经世心,古人难尽了。
-- 柳宗元 《独觉》