zoukankan      html  css  js  c++  java
  • 用C++语言实现目录文件的非递归遍历并用仿函数来进行文件操作

    编程语言:C++
    类 别:(实用算法)
    主要功能:用C++语言实现目录文件的非递归遍历并用伪函数来进行文件操作

        在用进行文件操作时,少不了和目录的递归打交道,但我一般认为.递归算法比较慢.如果可以采用非递归实现,就不要递归.
       
        在非递归算法中,一般我们用一个队列来保存相应的数据.一会列出代码.
        还有一个问题,我们递归目录,无非是想对文件进行操作,或者想得到文件的一个列表. 这时,你可以会采用回调函数. 但在我看来,还有更好的实现文案,让"回调"函数是一个对象,就既可以实现回调,也可以保存数据,这就是C++语言的仿函数.今天,我们就用仿函数来对指定的文件进行操作,例如修改文件,或者得到文件列表.
       
        先看一下递归函数的实现:

    bool FindPathFiles(LPCTSTR pPath, LPCTSTR pExt, bool includeSubdir,FileOperator* fileOperator]/* = NULL : 这个是仿函数的指针,一会用来对每个文件进行操作 */)
    {
    WIN32_FIND_DATA fd;
    list<tstring> directories;  // 这里就是保存递归数据,保存目录
    directories.push_back(tstring(pPath));

    while(directories.size() > 0)
    {
      tstring path 
    = directories.front();
      directories.pop_front();
      tstring pathFind 
    = path + _T("\\*");
      HANDLE hFind 
    = NULL;
      hFind 
    = ::FindFirstFile(pathFind.c_str(),&fd);
      
    if (hFind == INVALID_HANDLE_VALUE) 
      
    {
      
    return false;
      }
     
      
    bool bFinished = false;
      
    while(!bFinished)
      
    {
      
    if(fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
      
    {
        
    //是目录,如果不是父目录或者当前目录,则把目录压要待处理的目录列表中.
       tstring strFileName(fd.cFileName);
        
    if(includeSubdir)
        
    {
        
    if(strFileName != _T("."&& strFileName != _T(".."))
        
    {
          directories.push_back(path 
    + _T("\\"+ strFileName);
        }

        }

      }

      
    else
      
    {
        
    if(fileOperator)
        
    {
        
    // 目录操作
        (*fileOperator)(path, &fd);
       }

        
    else
        
    {
        wcout 
    << fd.cFileName << endl;
        }

      }

      BOOL bRet 
    = ::FindNextFile(hFind,&fd);
      
    if(!bRet)
      
    {
        bFinished 
    = true;
      }

      }

      ::FindClose(hFind);
    }

    return true;
    }


    上面的部分,着重说明非递归的实现要点,FileOperator* fileOperator,是仿函数的操作

        我们再来看一下,如何定义属全上面的仿函数,再写一个抽象基类:
    class FileOperator
    {
    public:
    virtual void operator()(const tstring& path, LPWIN32_FIND_DATA pfdd) = NULL;
    }
    ;

        如果我们对每个文件进行操作,我们这样来定义,下面一个例子,是我对第个 EXE 文件进行一下修复操作:
    class FixEBOOK : public FileOperator
    {
    protected:
    bool TryFixVirusBook(tstring file)
    {
      
    return true;
    }

    public:
    void operator()(const tstring& path, LPWIN32_FIND_DATA pfd)
    {
      WIN32_FIND_DATA
    & fd = *pfd;
      tstring file(path 
    + _T("\\"+ fd.cFileName);
      tstring fileExt 
    = file.substr(file.rfind('.'));
      transform(fileExt.begin(),fileExt.end(),fileExt.begin(),tolower);
      
    if(fileExt != _T(".exe"))
      
    return;
      
      
    //操作
      this->TryFixVirusBook(file);

      
    return;
    }

    }


    //////////////////////////////////////////////
    //声明操作
    FixEBOOK oper;
    //遍历每个文件,进行操作
    FindPathFiles(szCurrentPath,_T(".exe"),true&oper);

      如果我们想得到文件列表,则可以这样写:
    class FileListOper : public FileOperator
    {
    protected:
    list
    <tstring> m_files;
    list
    <tstring>& GetFiles(voidconst
    {
      
    return m_files;
    }

    public:
    void operator()(const tstring& path, LPWIN32_FIND_DATA pfd)
    {
      WIN32_FIND_DATA
    & fd = *pfd;
      tstring file(path 
    + _T("\\"+ fd.cFileName);

      m_files.push_back(file);
      
    return;
    }

    }


    //////////////////////////////////////////////////////////////////
    //声明操作
    FileListOper oper;
    //遍历每个文件,进行操作
    FindPathFiles(szCurrentPath,_T(".exe"),true&oper);

      
    const  list<tstring>& files = oper.GetFiles();

        希望大家拍砖讨论
  • 相关阅读:
    django-3-模板变量,过滤器,静态文件的引用
    django-2-路由配置及渲染方式
    用pycharm运行django项目
    django-1-框架介绍
    django-6-数据库配置及模型创建,激活(django模型系统1)
    用Sklearn实现聚类算法并用散点图展现效果
    方差、标准差、协方差、协方差相关系数
    ARIMa--时间序列模型
    人工智能--第二天--KNN算法实现
    人工智能--第二天--KNN算法
  • 原文地址:https://www.cnblogs.com/evlon/p/809391.html
Copyright © 2011-2022 走看看