代码
getFiles()
函数的作用:
path是一个文件夹路径,函数在path
文件夹下寻找所有文件(包括子文件夹下的文件),然后将所有文件的路径存入files
#include <io.h> //实现功能需要包含头文件io.h
void getFiles(string path, vector<string>& files)
{
intptr_t hFile = 0;//文件句柄,过会儿用来查找
struct _finddata_t fileinfo;//文件信息
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);
}
else//如果是文件
{
files.push_back(p.assign(path).append("\").append(fileinfo.name));
}
} while (_findnext(hFile, &fileinfo) == 0); //能寻找到其他文件
_findclose(hFile); //结束查找,关闭句柄
}
}
代码解读
_finddata_t
它是存储一个文件相关信息的结构体,查看其定义:
#ifdef _USE_32BIT_TIME_T
#define _finddata_t _finddata32_t
#define _finddatai64_t _finddata32i64_t
#else
#define _finddata_t _finddata64i32_t
#define _finddatai64_t __finddata64_t
#endif
我这里是_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
是该结构体的一个成员,是attribute(属性)的缩写。
它代表文件的属性,下边是相应的宏
#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
成员name
就是文件名字嘛..…
_findfirst
第一个参数是标明文件的字符串,可支持通配符:*.c
代表后缀为.c的文件,*
就代表所有文件
第二个参数是_finddata_t
类型变量的地址。该变量用来保存文件信息。
这有坑
我跟网上有点不同的是,网上我看到的例子定义的hFile
都是long
型,我用long
型打开文件就出问题了。
其实VS已经警告了warning C4244: “=”: 从“intptr_t”转换到“long”,可能丢失数据
。
我没在意它,后来改掉了类型就成功了。(就冲这一点,VS天下第一!)
查看_findfirst
定义
#ifdef _USE_32BIT_TIME_T
#define _findfirst _findfirst32
#define _findnext _findnext32
#define _findfirsti64 _findfirst32i64
#define _findnexti64 _findnext32i64
#else
#define _findfirst _findfirst64i32
#define _findnext _findnext64i32
#define _findfirsti64 _findfirst64
#define _findnexti64 _findnext64
#endif
我这里用的是_findfirst64i32
,查看其定义
_ACRTIMP intptr_t __cdecl _findfirst64i32(
_In_z_ char const* _FileName,
_Out_ struct _finddata64i32_t* _FindData
);
说明函数返回intptr_t
继续查看intptr_t
定义,得到
#ifdef _WIN64
typedef unsigned __int64 size_t;
typedef __int64 ptrdiff_t;
typedef __int64 intptr_t;
#else
typedef unsigned int size_t;
typedef int ptrdiff_t;
typedef int intptr_t;
所以intptr_t
在我电脑上实际是__int64
,转换成long可能会丢失数据。
_findnext
查看其定义
#ifdef _USE_32BIT_TIME_T
#define _findfirst _findfirst32
#define _findnext _findnext32
#define _findfirsti64 _findfirst32i64
#define _findnexti64 _findnext32i64
#else
#define _findfirst _findfirst64i32
#define _findnext _findnext64i32
#define _findfirsti64 _findfirst64
#define _findnexti64 _findnext64
#endif
我这里是_findnext64i32
,查看其定义
_ACRTIMP int __cdecl _findnext64i32(
_In_ intptr_t _FindHandle,
_Out_ struct _finddata64i32_t* _FindData
);
没啥讲的,好好看看_findfirst
部分就懂这个了。
位运算
fileinfo.attrib & _A_SUBDIR
,代码中用到了按位与&。在此表示是文件夹(subdirectory)。位运算经常用在表示属性。具体的这次先不讲。
作者:@臭咸鱼
本文为作者原创,转载请注明出处:https://chouxianyu.github.io
欢迎转发和评论!