zoukankan      html  css  js  c++  java
  • C++下遍历文件夹

    编写程序遍历文件夹及其子文件夹下所有文件,并输出到标准输出流或者文件流。

    1. 先考虑在单层目录下,遍历所有文件。以C:WINDOWS为例:

    用到数据结构_finddata_t,文件信息结构体的指针。

    复制代码
    struct _finddata_t
    {
    unsigned attrib; //文件属性
    time_t time_create; //文件创建时间
    time_t time_access; //文件上一次访问时间
    time_t time_write; //文件上一次修改时间
    _fsize_t size; //文件字节数
    char name[_MAX_FNAME]; //文件名
    };
    复制代码

    文件属性是无符号整数,取值为相应的宏:_A_ARCH(存档),_A_SUBDIR(文件夹),_A_HIDDEN(隐藏),_A_SYSTEM(系统),_A_NORMAL(正常),_A_RDONLY(只读)。容易看出,通过这个结构体,我们可以得到关于该文件的很多信息。结合以下函数,我们可以将文件信息存储到这个结构体中:

    //按FileName命名规则匹配当前目录第一个文件
    _findfirst(_In_ const char * FileName, _Out_ struct _finddata64i32_t * _FindData);
    //按FileName命名规则匹配当前目录下一个文件
    _findnext(_In_ intptr_t _FindHandle, _Out_ struct _finddata64i32_t * _FindData);
    //关闭_findfirst返回的文件句柄
    _findclose(_In_ intptr_t _FindHandle);

    _findfirst 函数返回的是匹配到文件的句柄,数据类型为long。遍历过程可以指定文件类型,这通过FileName的赋值来实现,例如要遍历C:WINDOWS下的所有.exe文件


    bool transfer(string fileName = "C:\Windows\*.exe", int exeNum = 0)
    {
    _finddata_t fileInfo;
    long handle = _findfirst(fileName.c_str(), &fileInfo);

    if (handle == -1L)
    {
    cerr << "failed to transfer files" << endl;
    return false;
    }

    do
    {
    exeNum ++;
    cout << fileInfo.name <<endl;
    } while (_findnext(handle, &fileInfo) == 0);
    cout << " .exe files' number: " << exeNum << endl;

    return true;
    }

    复制代码
    bool transfer(string fileName = "C:\Windows\*.exe", int exeNum = 0)
    {
    _finddata_t fileInfo;
    long handle = _findfirst(fileName.c_str(), &fileInfo);

    if (handle == -1L)
    {
    cerr << "failed to transfer files" << endl;
    return false;
    }

    do
    {
    exeNum ++;
    cout << fileInfo.name <<endl;
    } while (_findnext(handle, &fileInfo) == 0);
    cout << " .exe files' number: " << exeNum << endl;

    return true;
    }
    复制代码

     2. 遍历文件夹及其子文件夹下所有文件。操作系统中文件夹目录是树状结构,使用深度搜索策略遍历所有文件。用到_A_SUBDIR属性,可运行程序如下:

    void dfsFolder(string folderPath, ofstream &fout)
    {
    _finddata_t FileInfo;
    string strfind = folderPath + "\*";
    long Handle = _findfirst(strfind.c_str(), &FileInfo);

    if (Handle == -1L)
    {
    cerr << "can not match the folder path" << endl;
    exit(-1);
    }
    do{
    //判断是否有子目录
    if (FileInfo.attrib & _A_SUBDIR)
    {
    //这个语句很重要
    if( (strcmp(FileInfo.name,".") != 0 ) &&(strcmp(FileInfo.name,"..") != 0))
    {
    string newPath = folderPath + "\" + FileInfo.name;
    dfsFolder(newPath, fout);
    }
    }
    else
    {
    fout << folderPath << "\" << FileInfo.name << " ";
    }
    }while (_findnext(Handle, &FileInfo) == 0);

    _findclose(Handle);
    fout.close();
    }


    复制代码
    void dfsFolder(string folderPath, ofstream &fout)
    {
    _finddata_t FileInfo;
    string strfind = folderPath + "\*";
    long Handle = _findfirst(strfind.c_str(), &FileInfo);

    if (Handle == -1L)
    {
    cerr << "can not match the folder path" << endl;
    exit(-1);
    }
    do{
    //判断是否有子目录
    if (FileInfo.attrib & _A_SUBDIR)
    {
    //这个语句很重要
    if( (strcmp(FileInfo.name,".") != 0 ) &&(strcmp(FileInfo.name,"..") != 0))
    {
    string newPath = folderPath + "\" + FileInfo.name;
    dfsFolder(newPath, fout);
    }
    }
    else
    {
    fout << folderPath << "\" << FileInfo.name << " ";
    }
    }while (_findnext(Handle, &FileInfo) == 0);

    _findclose(Handle);
    fout.close();
    }
    复制代码

     在判断有无子目录的if分支中,由于系统在进入一个子目录时,匹配到的头两个文件(夹)是"."(当前目录),".."(上一层目录)。需要忽略掉这两种情况。当需要对遍历到的文件做处理时,在else分支中添加相应的代码就好

  • 相关阅读:
    c语言知识
    数字地与模拟地
    C语言实现顺序表(增删)
    传统数据库、Nosql数据库与云数据库区别?
    大数据处理架构如何
    warning: implicit declaration of function 'func1' [-Wimplicit-function-declaration]
    window10创建virtualenv虚拟环境
    二叉树的实现以及三种遍历方法--代码
    损失函数--KL散度与交叉熵
    市场回测与对冲套利
  • 原文地址:https://www.cnblogs.com/byteHuang/p/9534836.html
Copyright © 2011-2022 走看看