C++獲取文件夾下所有文件的路徑


代碼

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

歡迎轉發和評論!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM