用VC++遍历目录代码

来源:本站
导读:目前正在解读《用VC++遍历目录代码》的相关信息,《用VC++遍历目录代码》是由用户自行发布的知识型内容!下面请观看由(电工技术网 - www.9ddd.net)用户发布《用VC++遍历目录代码》的详细说明。
简介:本文给大家分享了用VC++遍历目录代码。

---- 所谓遍历目录,就是给定一个目录,访问其中的所有文件(包括子目录下的文件)。迭代是比较常用的遍历算法。本文利用C++面向对象的特性,通过一个类CBrowseDir,对目录遍历进行了封装。用户只需掌握该类四个成员函数的用法,就可以在自己的程序中,很方便地实现目录遍历。

---- 类CBrowseDir使用了迭代算法。因为算法不是本文重点,笔者不打算展开进一步讨论,对其感兴趣者可参考相关资料。

一、类成员函数说明:

---- bool SetInitDir(const char *dir);

---- 功能:设置要遍历的目录。

---- 参数:dir 指向要遍历的目录,可以使用相对路径,比如"d:..hawk";还可以使用网络路径,比如"\wfdhawk"(其中wf是主机名,d是共享目录,hawk是目录)。

---- 返回值:返回true,表示设置成功;返回false,说明目录不可用。

---- bool BeginBrowse(const char *filespec);

---- 功能:开始遍历目录中由filespec指定的文件(包括隐藏文件)。

---- 参数:filespec 指定文件类型,可以使用通配符*和?,比如"*.exe"或"a?.*"都是合法参数。注意:filespec中不能包含路径,象"hawk*.*"是错误的。

---- 返回值:函数返回true,表明已顺利遍历完所有文件;返回false,遍历过程被用户中止。

---- virtual bool ProcessFile(const char *filename);

---- 功能:虚函数。每找到一个文件,程序就会调用ProcessFile,并把文件名作为参数传递给函数。如果函数返回false,则强制遍历中止,并导致类成员函数函数BeginBrowse返回false。 用户应该覆写此函数,以加入自己的处理代码。

---- 参数:filename 指向一个文件名。注意:filename使用绝对路径。

---- 返回值:返回true,继续遍历;否则,中止遍历。

---- virtual void ProcessDir (const char *currentdir,const char *parentdir);

---- 功能:虚函数。在遍历过程中,每进入一个子目录,程序就会调用ProcessDir,并把目录名及其上一级目录名作为参数传递给函数。如果该目录是成员函数SetInitDir指定的初始目录,则parentdir=NULL。用户可以覆写此函数,以加入自己的处理代码。比如可以在这里统计子目录的个数。

---- 参数:currentdir 指向一个子目录。

---- parentdir 指向currentdir的父目录。

---- 注意:currentdir和parentdir均使用绝对路径。

二、使用:

---- 把类CBrowseDir的头文件BrowseDir.h及实现文件BrowseDir.cpp加到项目(Project)中,然后派生自己的类并覆写虚函数ProcessFile和ProcessDir。遍历目录时,先构造一个派生类对象,用成员函数SetInitDir指定目录,然后调用BeginBrowse开始遍历。

---- 本文提供了一个例子 example.cpp,它从CBrowseDir派生出子类CStatDir,通过统计函数ProcessFile及ProcessDir的调用次数,可以得知目录中的文件及子目录个数。程序都有注释,这里就不再罗嗦了。

三、注意事项:

---- 1. 类CBrowseDir会改变当前工作目录。同一个相对路径,使用CBrowseDir前后,可能会有不同的含义。因此用户编程时,要小心使用相对路径。

---- 2. 如果项目(Project)是一个MFC应用程序,直接加入BrowseDir.h及BrowseDir.cpp会导致编译出错。这是因为缺省情况下,MFC项目使用了预编译头(Precompiled Header),而BrowseDir.h和BrowseDir.cpp是用标准C++语句编写的,没用预编译。一个解决办法是先用类向导生成类CBrowseDir的"架子",再把相应的代码拷贝过去。

---- 本文代码均在Win95、Visual C++ 5.0环境下调试通过。

附源代码:

/**************************************************   这是CBrowseDir的类定义文件 BrowseDir.h /**************************************************#include "stdlib.h"class CBrowseDir{protected://存放初始目录的绝对路径,以''结尾char m_szInitDir[_MAX_PATH];public://缺省构造器CBrowseDir();//设置初始目录为dir,如果返回false,表示目录不可用bool SetInitDir(const char *dir);//开始遍历初始目录及其子目录下由filespec指定类型的文件//filespec可以使用通配符 * ?,不能包含路径。//如果返回false,表示遍历过程被用户中止bool BeginBrowse(const char *filespec);protected://遍历目录dir下由filespec指定的文件//对于子目录,采用迭代的方法//如果返回false,表示中止遍历文件bool BrowseDir(const char *dir,const char *filespec);//函数BrowseDir每找到一个文件,就调用ProcessFile//并把文件名作为参数传递过去//如果返回false,表示中止遍历文件//用户可以覆写该函数,加入自己的处理代码virtual bool ProcessFile(const char *filename);//函数BrowseDir每进入一个目录,就调用ProcessDir//并把正在处理的目录名及上一级目录名作为参数传递过去//如果正在处理的是初始目录,则parentdir=NULL//用户可以覆写该函数,加入自己的处理代码//比如用户可以在这里统计子目录的个数virtual void ProcessDir(const char *currentdir,const char *parentdir);};/*********************************************/这是CBrowseDir的类实现文件 BrowseDir.cpp/***********************************************/#include "stdlib.h"#include "direct.h"#include "string.h"#include "io.h"#include "browsedir.h"CBrowseDir::CBrowseDir(){//用当前目录初始化m_szInitDirgetcwd(m_szInitDir,_MAX_PATH);//如果目录的最后一个字母不是'',则在最后加上一个''int len=strlen(m_szInitDir);if (m_szInitDir[len-1] != '\')strcat(m_szInitDir,"\");}bool CBrowseDir::SetInitDir(const char *dir){//先把dir转换为绝对路径if (_fullpath(m_szInitDir,dir,_MAX_PATH) == NULL)return false;//判断目录是否存在if (_chdir(m_szInitDir) != 0)return false;//如果目录的最后一个字母不是'',则在最后加上一个''int len=strlen(m_szInitDir);if (m_szInitDir[len-1] != '\')strcat(m_szInitDir,"\");return true;}bool CBrowseDir::BeginBrowse(const char *filespec){ProcessDir(m_szInitDir,NULL);return BrowseDir(m_szInitDir,filespec);}bool CBrowseDir::BrowseDir(const char *dir,const char *filespec){_chdir(dir);//首先查找dir中符合要求的文件long hFile;_finddata_t fileinfo;if ((hFile=_findfirst(filespec,&fileinfo)) != -1){do{//检查是不是目录//如果不是,则进行处理if (!(fileinfo.attrib & _A_SUBDIR)){char filename[_MAX_PATH];strcpy(filename,dir);strcat(filename,fileinfo.name);if (!ProcessFile(filename))return false;}} while (_findnext(hFile,&fileinfo) == 0);_findclose(hFile);}//查找dir中的子目录//因为在处理dir中的文件时,派生类的ProcessFile有可能改变了//当前目录,因此还要重新设置当前目录为dir。//执行过_findfirst后,可能系统记录下了相关信息,因此改变目录//对_findnext没有影响。_chdir(dir);if ((hFile=_findfirst("*.*",&fileinfo)) != -1){do{//检查是不是目录//如果是,再检查是不是 . 或 .. //如果不是,进行迭代if ((fileinfo.attrib & _A_SUBDIR)){if (strcmp(fileinfo.name,".") != 0 && strcmp(fileinfo.name,"..") != 0){char subdir[_MAX_PATH];strcpy(subdir,dir);strcat(subdir,fileinfo.name);strcat(subdir,"\");ProcessDir(subdir,dir);if (!BrowseDir(subdir,filespec))return false;}}  } while (_findnext(hFile,&fileinfo) == 0);_findclose(hFile);}return true;}bool CBrowseDir::ProcessFile(const char *filename){return true;}void CBrowseDir::ProcessDir(const char *currentdir,const char *parentdir){}/*************************************************这是例子example.cpp   /*************************************************#include "stdio.h"#include "BrowseDir.h"//从CBrowseDir派生出的子类,用来统计目录中的文件及子目录个数class CStatDir:public CBrowseDir{protected:int m_nFileCount;   //保存文件个数int m_nSubdirCount; //保存子目录个数public://缺省构造器CStatDir(){//初始化数据成员m_nFileCount和m_nSubdirCountm_nFileCount=m_nSubdirCount=0;}//返回文件个数int GetFileCount(){return m_nFileCount;}//返回子目录个数int GetSubdirCount(){//因为进入初始目录时,也会调用函数ProcessDir,//所以减1后才是真正的子目录个数。return m_nSubdirCount-1;}protected://覆写虚函数ProcessFile,每调用一次,文件个数加1virtual bool ProcessFile(const char *filename){m_nFileCount++;return CBrowseDir::ProcessFile(filename);}//覆写虚函数ProcessDir,每调用一次,子目录个数加1virtual void ProcessDir(const char *currentdir,const char *parentdir){m_nSubdirCount++;CBrowseDir::ProcessDir(currentdir,parentdir);}};void main(){//获取目录名char buf[256];printf("请输入要统计的目录名:");gets(buf);//构造类对象CStatDir statdir;//设置要遍历的目录if (!statdir.SetInitDir(buf)){puts("目录不存在。");return;}//开始遍历statdir.BeginBrowse("*.*");//统计结果中,子目录个数不含 . 及 ..printf("文件总数: %dn子目录总数: %dn",statdir.GetFileCount(),statdir.GetSubdirCount());}

提醒:《用VC++遍历目录代码》最后刷新时间 2024-03-14 00:58:35,本站为公益型个人网站,仅供个人学习和记录信息,不进行任何商业性质的盈利。如果内容、图片资源失效或内容涉及侵权,请反馈至,我们会及时处理。本站只保证内容的可读性,无法保证真实性,《用VC++遍历目录代码》该内容的真实性请自行鉴别。