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);
}
}
覺來窗牖空,寥落雨聲曉。
良游怨遲暮,末事驚紛擾。
為問經世心,古人難盡了。
-- 柳宗元 《獨覺》
