C++枚举某个目录下所有文件

C++枚举某个目录下所有文件

标签(空格分隔): iso c++


c++提供文件遍历的方法如下
一个结构体
三个函数


struct _finddata32_t
{
    unsigned    attrib;         //文件属性
    __time32_t  time_create;    // 创建时间
    __time32_t  time_access;    // 最后访问时间
    __time32_t  time_write;     //最后写入时间
    _fsize_t    size;           //文件大小
    char        name[260];      //文件名
};

文件有如下属性

// File attribute constants for the _findfirst() family of functions
#define _A_NORMAL 0x00 // 正常文件没有读写限制
#define _A_RDONLY 0x01 // 只读文件
#define _A_HIDDEN 0x02 // 隐藏文件
#define _A_SYSTEM 0x04 // 系统文件
#define _A_SUBDIR 0x10 // 目录
#define _A_ARCH   0x20 // 存档文件

枚举文件

intptr_t _findfirst(  
   const char *filespec,  
   struct _finddata_t *fileinfo   
);  
intptr_t _findfirst32(  
   const char *filespec,  
   struct _finddata32_t *fileinfo   
);  
intptr_t _findfirst64(  
   const char *filespec,  
   struct _finddata64_t *fileinfo   
);  
intptr_t _findfirsti64(  
   const char *filespec,  
   struct _finddatai64_t *fileinfo   
);  
intptr_t _findfirst32i64(  
   const char *filespec,  
   struct _finddata32i64_t *fileinfo   
);  
intptr_t _findfirst64i32(  
   const char *filespec,  
   struct _finddata64i32_t *fileinfo   
);  
intptr_t _wfindfirst(  
   const wchar_t *filespec,  
   struct _wfinddata_t *fileinfo   
);  
intptr_t _wfindfirst32(  
   const wchar_t *filespec,  
   struct _wfinddata32_t *fileinfo   
);  
intptr_t _wfindfirst64(  
   const wchar_t *filespec,  
   struct _wfinddata64_t *fileinfo   
);  
intptr_t _wfindfirsti64(  
   const wchar_t *filespec,  
   struct _wfinddatai64_t *fileinfo   
);  
intptr_t _wfindfirst32i64(  
   const wchar_t *filespec,  
   struct _wfinddata32i64_t *fileinfo   
);  
intptr_t _wfindfirst64i32(  
   const wchar_t *filespec,  
   struct _wfinddata64i32_t *fileinfo   
);  

参数:
建议使用 Visual Studio 2017 立即下载
_findfirst、_findfirst32、_findfirst32i64、_findfirst64、_findfirst64i32、_findfirsti64、_wfindfirst、_wfindfirst32、_wfindfirst32i64、_wfindfirst64、_wfindfirst64i32、_wfindfirsti64
Visual Studio 2015 其他版本

发布日期: 2016年7月

若要了解有关 Visual Studio 2017 RC 的最新文档,请参阅 Visual Studio 2017 RC 文档。

提供有关匹配中指定的文件的文件名的第一个实例的信息filespec参数。

intptr_t _findfirst(  
   const char *filespec,  
   struct _finddata_t *fileinfo   
);  
intptr_t _findfirst32(  
   const char *filespec,  
   struct _finddata32_t *fileinfo   
);  
intptr_t _findfirst64(  
   const char *filespec,  
   struct _finddata64_t *fileinfo   
);  
intptr_t _findfirsti64(  
   const char *filespec,  
   struct _finddatai64_t *fileinfo   
);  
intptr_t _findfirst32i64(  
   const char *filespec,  
   struct _finddata32i64_t *fileinfo   
);  
intptr_t _findfirst64i32(  
   const char *filespec,  
   struct _finddata64i32_t *fileinfo   
);  
intptr_t _wfindfirst(  
   const wchar_t *filespec,  
   struct _wfinddata_t *fileinfo   
);  
intptr_t _wfindfirst32(  
   const wchar_t *filespec,  
   struct _wfinddata32_t *fileinfo   
);  
intptr_t _wfindfirst64(  
   const wchar_t *filespec,  
   struct _wfinddata64_t *fileinfo   
);  
intptr_t _wfindfirsti64(  
   const wchar_t *filespec,  
   struct _wfinddatai64_t *fileinfo   
);  
intptr_t _wfindfirst32i64(  
   const wchar_t *filespec,  
   struct _wfinddata32i64_t *fileinfo   
);  
intptr_t _wfindfirst64i32(  
   const wchar_t *filespec,  
   struct _wfinddata64i32_t *fileinfo   
);  

参数
filespec
目标文件规范 (可以包含通配符字符)。

fileinfo
文件信息的缓冲区。

返回值
如果成功,_findfirst返回标识的文件或与匹配的文件组的唯一的搜索句柄,可在后续调用_findnext或_findclose。 否则为_findfirst返回 –&1; 并设置errno为以下值之一。

EINVAL
无效的参数︰filespec或fileinfo已NULL。 或者,操作系统返回了意外的错误。

ENOENT
无法将匹配的文件规范。

ENOMEM
内存不足。

EINVAL
无效文件名规范 (或指定的文件名) 不大于MAX_PATH。

有关这些属性和其他的更多信息返回代码示例,请参见 _doserrno、errno、_sys_errlist 和 _sys_nerr。

int _findnext(  
   intptr_t handle,  
   struct _finddata_t *fileinfo   
);  
int _findnext32(  
   intptr_t handle,  
   struct _finddata32_t *fileinfo   
);  
int _findnext64(  
   intptr_t handle,  
   struct __finddata64_t *fileinfo   
);  
int _findnexti64(  
   intptr_t handle,  
   struct __finddatai64_t *fileinfo   
);  
int _findnext32i64(  
   intptr_t handle,  
   struct _finddata32i64_t *fileinfo   
);  
int _findnext64i32(  
   intptr_t handle,  
   struct _finddata64i32_t *fileinfo   
);  
int _wfindnext(  
   intptr_t handle,  
   struct _wfinddata_t *fileinfo   
);  
int _wfindnext32(  
   intptr_t handle,  
   struct _wfinddata32_t *fileinfo   
);  
int _wfindnext64(  
   intptr_t handle,  
   struct _wfinddata64_t *fileinfo   
);  
int _wfindnexti64(  
   intptr_t handle,  
   struct _wfinddatai64_t *fileinfo   
);  
int _wfindnext32i64(  
   intptr_t handle,  
   struct _wfinddatai64_t *fileinfo   
);  
int _wfindnext64i32(  
   intptr_t handle,  
   struct _wfinddata64i32_t *fileinfo   
);  

参数
handle
搜索句柄返回到以前调用_findfirst。

fileinfo
文件信息的缓冲区。

返回值
如果成功,返回 0。 否则为返回 –&1; 并设置errno到一个值,该值故障的性质。 下表中显示可能的错误代码。

EINVAL
无效的参数︰fileinfo已NULL。 或者,操作系统返回了意外的错误。

ENOENT
找不到没有更多匹配的文件。

ENOMEM
没有足够的内存或文件名称的长度超出MAX_PATH。

示例

#pragma once


class CEnumFile
{
public:
    CEnumFile();
    CEnumFile(std::string szPath,std::string szEx = "*.*");
    ~CEnumFile();

    enum {
        ATTRIB_ARCH     =   _A_ARCH,        //存档文件
        ATTRIB_HIDDEN   =   _A_HIDDEN,      //隐藏文件
        ATTRIB_NORMAL   =   _A_NORMAL,      //正常文件
        ATTRIB_RDONLY   =   _A_RDONLY,      //只读文件
        ATTRIB_SYSTEM   =   _A_SYSTEM,      //系统文件
        ATTRIB_SUBDIR   =   _A_SUBDIR       //目录
    };
    //设置过滤条件
    void SetFilter(std::string szPath, std::string szEx = "*.*");
    //枚举所有文件
    std::vector<std::string> EnumFile();

    //获取文件访问属性
    unsigned GetFileAttrib(std::string szFileName);

    //获取文件创建时间
    time_t GetCreateTime(std::string szFileName);

    //获取文件最后访问时间
    time_t GetLastAccessTime(std::string FileName);

    //获取最后写入时间
    time_t GetLastWriteTime(std::string FileName);


private:
    std::string m_szPath;       //文件路径
    std::string m_szEx;         //文件扩展名
    std::string m_szFilter;     //枚举过滤
    std::string m_szErrorInfo;  //错误信息
    std::map<std::string,_finddata_t>   m_mapFindData;  //文件信息

};

#include "stdafx.h"
#include "EnumFile.h"
#include <io.h>
#include <sstream>
#include <assert.h>
using namespace std;

#define ExceptionHead "["<<__FUNCTION__ << "-" << __LINE__ <<"]"

CEnumFile::CEnumFile()
    :m_szPath("")
    ,m_szEx("")
{
}

CEnumFile::CEnumFile(string szPath, string szEx)
    :m_szPath(szPath)
    ,m_szEx(szEx)
{
    SetFilter(szPath, szEx);
}

CEnumFile::~CEnumFile()
{
}

void CEnumFile::SetFilter(std::string szPath, std::string szEx)
{
    m_szPath = szPath;
    m_szEx = szEx;

    stringstream ss;
    ss << m_szPath << "/" << m_szEx;
    ss >> m_szFilter;
}

vector<string> CEnumFile::EnumFile()
{
    _finddata_t  FindData;

    vector<string> vecRes;

    intptr_t FileIndes = _findfirst(m_szFilter.c_str(), &FindData);
    assert(-1 != FileIndes);
    if (FileIndes < 0)
    {
        stringstream ss;
        ss <<ExceptionHead<< endl;
        ss >> m_szErrorInfo;
        perror(m_szErrorInfo.c_str());
        throw std::exception(m_szErrorInfo.c_str());
    }
    //记录
    vecRes.push_back(FindData.name);
    m_mapFindData.insert(make_pair(FindData.name, FindData));

    //遍历
    while (_findnext(FileIndes,&FindData) >= 0)
    {
        //插入
        vecRes.push_back(FindData.name);
        m_mapFindData.insert(make_pair(FindData.name, FindData));
    }
    _findclose(FileIndes);

    return vecRes;
}

//获取文件访问属性
unsigned CEnumFile::GetFileAttrib(string szFileName)
{
    auto iter = m_mapFindData.find(szFileName);
    if (iter == m_mapFindData.end())
    {
        stringstream ss;
        ss << ExceptionHead<<"目录" << m_szPath << "下" << "不存在此文件" << endl;
        ss >> m_szErrorInfo;
        perror(m_szErrorInfo.c_str());
        throw std::exception(m_szErrorInfo.c_str());
    }

    return iter->second.attrib;
}

//获取文件创建时间
time_t CEnumFile::GetCreateTime(string szFileName)
{
    auto iter = m_mapFindData.find(szFileName);
    if (iter == m_mapFindData.end())
    {
        stringstream ss;
        ss << ExceptionHead << "目录" << m_szPath << "下" << "不存在此文件" << endl;
        ss >> m_szErrorInfo;
        perror(m_szErrorInfo.c_str());
        throw std::exception(m_szErrorInfo.c_str());
    }

    return iter->second.time_create;

}

//获取文件最后访问时间
time_t CEnumFile::GetLastAccessTime(string szFileName)
{
    auto iter = m_mapFindData.find(szFileName);
    if (iter == m_mapFindData.end())
    {
        stringstream ss;
        ss << ExceptionHead << "目录" << m_szPath << "下" << "不存在此文件" << endl;
        ss >> m_szErrorInfo;
        perror(m_szErrorInfo.c_str());
        throw std::exception(m_szErrorInfo.c_str());
    }

    return iter->second.time_access;
}

//获取最后写入时间
time_t CEnumFile::GetLastWriteTime(string szFileName)
{
    auto iter = m_mapFindData.find(szFileName);
    if (iter == m_mapFindData.end())
    {
        stringstream ss;
        ss << ExceptionHead << "目录" << m_szPath << "下" << "不存在此文件" << endl;
        ss >> m_szErrorInfo;
        perror(m_szErrorInfo.c_str());
        throw std::exception(m_szErrorInfo.c_str());
    }

    return iter->second.time_write;
}
// EnumFile.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <sstream>
#include <time.h>
#include <assert.h>
#include "EnumFile.h"
using namespace std;

#pragma warning(disable:4996)

string FormatTime(time_t time,string szFormat)
{
    assert(szFormat.size() != 0);
    if (szFormat.size() == 0)
    {
        throw std::exception("格式化字符串为空");
    }

    tm* pTm;
    pTm = localtime(&time);
    string szRes(64, '\0');

    strftime(&szRes[0], szRes.size(), szFormat.c_str(), pTm);
    return szRes;
}

int main()
{
    try
    {
        CEnumFile enumFile("C:/Users/善军/Desktop");
        vector<string> vecFiles = enumFile.EnumFile();

        cout << vecFiles.size() << endl;
        for (auto item : vecFiles)
        {
            cout << item << ":" << FormatTime(enumFile.GetLastWriteTime(item),"%Y-%m-%d %H:%M:%S") << endl;
        }

    }
    catch (const std::exception& e)
    {
        cout << e.what() << endl;
    }


    return 0;
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值