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

欢迎转发和评论!

posted @ 2019-07-30 14:53  臭咸鱼  阅读(8482)  评论(0编辑  收藏  举报