代碼
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
歡迎轉發和評論!