编程语言:C++ 类 别:(实用算法) 主要功能:用C++语言实现目录文件的非递归遍历并用伪函数来进行文件操作 在用进行文件操作时,少不了和目录的递归打交道,但我一般认为.递归算法比较慢.如果可以采用非递归实现,就不要递归. 在非递归算法中,一般我们用一个队列来保存相应的数据.一会列出代码. 还有一个问题,我们递归目录,无非是想对文件进行操作,或者想得到文件的一个列表. 这时,你可以会采用回调函数. 但在我看来,还有更好的实现文案,让"回调"函数是一个对象,就既可以实现回调,也可以保存数据,这就是C++语言的仿函数.今天,我们就用仿函数来对指定的文件进行操作,例如修改文件,或者得到文件列表. 先看一下递归函数的实现:
![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif) ![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif) bool FindPathFiles(LPCTSTR pPath, LPCTSTR pExt, bool includeSubdir,FileOperator* fileOperator]/**//* = NULL : 这个是仿函数的指针,一会用来对每个文件进行操作 */)![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif) ![](https://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif) { WIN32_FIND_DATA fd; list directories; // 这里就是保存递归数据,保存目录 directories.push_back(tstring(pPath));![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif) while(directories.size() > 0)![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) ![](https://www.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif) { 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) ![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) { return false; } bool bFinished = false; while(!bFinished)![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) { if(fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) { //是目录,如果不是父目录或者当前目录,则把目录压要待处理的目录列表中. tstring strFileName(fd.cFileName); if(includeSubdir)![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) { if(strFileName != _T(".") && strFileName != _T(".."))![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) { directories.push_back(path + _T("\\") + strFileName); } } } else![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) { if(fileOperator)![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) { // 目录操作 (*fileOperator)(path, &fd); } else![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) { wcout TryFixVirusBook(file);![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif) return; } }![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif) ![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif) /**/////////////////////////////////////////////// //声明操作 FixEBOOK oper; //遍历每个文件,进行操作 FindPathFiles(szCurrentPath,_T(".exe"),true, &oper);![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
如果我们想得到文件列表,则可以这样写:
class FileListOper : public FileOperator![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif) ![](https://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif) { protected: list m_files; list& GetFiles(void) const![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) ![](https://www.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif) { return m_files; } public: void operator()(const tstring& path, LPWIN32_FIND_DATA pfd)![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) ![](https://www.cnblogs.com/Images/OutliningIndicators/ContractedSubBlock.gif) { WIN32_FIND_DATA& fd = *pfd; tstring file(path + _T("\\") + fd.cFileName);![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif) m_files.push_back(file); return; } }![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif) ![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif) /**/////////////////////////////////////////////////////////////////// //声明操作 FileListOper oper; //遍历每个文件,进行操作 FindPathFiles(szCurrentPath,_T(".exe"),true, &oper);![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif) const list& files = oper.GetFiles();
希望大家拍砖讨论
|