The so-called traversal directory is a given directory, access all files (including files in subdirectory). Iteration is a relatively common traversal algorithm. This article uses C object-oriented properties to package the directory traversal. Users only need to master the usage of the four member functions of the class, you can easily implement the directory traversal in your own program.
---- Class CBROWSEDIR uses iterative algorithm. Because the algorithm is not the focus of this article, the author does not intend to launch further discussion, and the interest of this can refer to the relevant information.
First, class member function description:
---- Bool SetinitDir (Const Char * Dir);
---- Features: Set the directory to be traversed.
---- Parameter: DIR points to the directory to be traversed, such as "D: ../ hawk"; you can also use the network path, such as "// wf / d / hawk" (where WF is the host name , D is a shared directory, Hawk is a directory).
---- Return Value: Return true, indicating that the setting is successful; return false, indicating that the directory is not available.
---- Bool Beginbrowse (Const Char * filespec);
---- Features: Start the files specified by the filepec in the directory (including hidden files).
---- Parameter: FileSpec Specifies the file type, you can use wildcard * and?, Such as "* .exe" or "a? *" Is all legitimate parameters. Note: The path cannot be included in FileSpec, like "hawk /*.*" is wrong.
---- Return value: The function returns true, indicating that all files have been successfully traversed; return False, the traversal process is aborted by the user.
---- Virtual Bool ProcessFile (Const Char * filename);
---- Function: virtual function. For each file, the program calls processfile and passes the file name as a parameter to the function. If the function returns false, force the traversal abort and causing the class member function function BeginBrowSE to return false. Users should overwrite this function to join your own processing code.
---- Parameter: FileName points to a file name. Note: FILENAME uses an absolute path.
---- Return Value: Return true, continue to traverse; otherwise, stop traversal.
---- Virtual Void ProcessDir (Const Char * Currentdir);
---- Function: virtual function. During the traversal, the program calls processdir every entering a subdirectory, and passes the directory name and its previous directory name to the function. If the directory is the initial directory specified by the member function setInitdir, ParentDir = NULL. Users can overwrite this function to join your own processing code. For example, you can count the number of subdires here.
---- Parameters: Currentdir points to a subdirectory. ---- Parentdir points to the parent directory of Currentdir. ---- Note: Currentdir and Parentdir use absolute paths.
Second, use:
---- Put the class CBROWSEDIR's header file Browsedir.h and implement file Browsedir.cpp Add to Project, and then derive your own class and override virtual functions processFile and ProcessDir. When traversing the catalog, construct a derived class object, specify the directory with member function setInitdir, and then call BeginBrowse to start traversing. ---- This article provides an example eXample.cpp, which is derived from CBROWSEDIR from CBROWSEDIR, and the number of files and subdirectory in the directory can be learned by the number of calls for the statistics processfile and processdir. The procedure has a comment, and it is no longer talented.
Third, pay attention:
---- 1. Class CBROWSEDIR will change the current work directory. The same relative path, there may be different meanings before and after using CBROWSEDIR. Therefore, be careful to use the relative path when programmed.
---- 2. If the project is a MFC application, join browsedir.h and browsedir.cpp can cause compilation errors. This is because the MFC project uses the precompiled header, and Browsedir.h and Browsedir.cpp are written in standard C statements without pre-compilation. A solution is to create a "shelf" for class CBROWSEDIR with class to copy the corresponding code.
---- This document is debugged in the Win95, Visual C 5.0 environment.
Attached code:
/ ************************************************** *
This is CBROWSEDIR class definition file Browsedir.h
/ ************************************************** *
#include "stdlib.h"
Class CBROWSEDIR
{
protected:
/ / Store the absolute path of the initial directory, ending with '/'
Char m_szinitdir [_max_path];
PUBLIC:
/ / Default constructor
CBROWSEDIR ();
/ / Set the initial directory to DIR, if false is returned, indicating that the directory is not available
Bool setInitdir; Const Char * Dir;
// Start traversing the initial directory and the file specified by the filepec
// filespec can use wildcard *?, it cannot contain paths.
// If false returns, it means that the traversal process is suspended by the user.
Bool Beginbrowse (Const Char * filespec);
protected:
// Traverse the file specified by filespec under DIR
/ / For subdirectory, use iteration method
// If you return false, indicate abort trailers
Bool Browsedir (Const Char * Dir, Const Char * FileSpec);
// Function Browsedir to call ProcessFile every finding a file
/ / And pass the file name as a parameter
// If you return false, indicate abort trailers
/ / The user can overwrite the function, join your own processing code
Virtual Bool ProcessFile (Const Char * filename);
// The function browsedir is called to call ProcessDir every time you enter a directory.
/ / And pass the directory name and the previous directory name that are being processed as a parameter
// If you are processing the initial directory, ParentDir = NULL
/ / The user can overwrite the function, join your own processing code
//, such as the number of users can count here
Virtual Void ProcessDir (Const Char * Currentdir);
}
/ *************************************************** /
This is CBROWSEDIR's class implementation file Browsedir.cpp
/ ***************************************************** /
#include "stdlib.h"
#include "direct.h"
#include "string.h"
#include "io.h"
#include "browsedir.h"
CBROWSEDIR :: CBROWSEDIR ()
{
// initialize m_szinitdir with the current directory
GetCWD (m_szinitdir, _max_path);
// If the last letter of the directory is not '/', then add one '/'
INT LEN = Strlen (m_szinitdir);
IF (m_szinitdir [len-1]! = '//')
STRCAT (m_szinitdir, "//");
}
Bool CBROWSEDIR :: SetinitDir (const char * dir)
{
// Convert DIR to an absolute path
IF (_FullPath (m_szinitdir, dir, _max_path) == null)
Return False;
/ / Judgment if the directory exists
IF (_chdir (m_szinitdir)! = 0)
Return False;
// If the last letter of the directory is not '/', then add one '/'
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);
/ / First find the document that meets the requirements in DIR
Long Hfile;
_finddata_t fileinfo;
IF ((hfile = _findfirst (filespec, & fileinfo))! = -1)
{
DO
{
// Check is the directory
// If not, it will be processed.
IF (! (fileinfo.attrib&& _a_subdir))
{
Char filename [_MAX_PATH];
STRCPY (Filename, DIR);
Strcat (filename, fileinfo.name);
IF (! ProcessFile (filename))
Return False;
}
} while (_findnext (hfindnext (hfindnext (hfindnext (hfindnext (hfindnex) == 0);
_findclose (hfile);
}
/ / Find the subdirectory in DIR
// Because when processed files in DIR, the processfile of the derived class may change.
// The current directory, so it is also necessary to reset the current directory as DIR.
// After performing _findfirst, the relevant information may be recorded in the system, so change the directory
// There is no impact on _findNext. _CHDIR (DIR);
IF ((hfile = _findfirst ("*. *", & fileinfo)! = -1)
{
DO
{
// Check is the directory
// If yes, check is it. Or ..
// If not, iterate
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 (hfindnext (hfindnext (hfindnext (hfindnext (hfindnex) == 0);
_findclose (hfile);
}
Return True;
}
BOOL CBROWSEDIR :: ProcessFile (const char * filename)
{
Return True;
}
Void CBROWSEDIR :: Processdir (Const Char)
* Currentdir, const char * parentdir)
{
}
/ **************************************************
This is example example eXample.cpp
/ **************************************************
#include "stdio.h"
#include "browsedir.h"
/ / Delicate the subclass of CBROWSEDIR to statistical directory and subdirectory
Class Cstatdir: Public CBROWSEDIR
{
protected:
INT m_nfilecount; // Save the number of files
INT M_NSUBDIRCOUNT; / / Save the subdirectory number
PUBLIC:
/ / Default constructor
CSTATDIR ()
{
// Initialization data member m_nfilecount and m_nsubdircount
m_nfilecount = m_nsubdircount = 0;
}
// Return to the number of files
Int getFileCount ()
{
Return m_nfilecount;
}
// Return the number of sub-directory
Int getSubdircount ()
{
// When entering the initial directory, the function ProcessDir will also be called.
// So it is a true sub-directory number after minus 1.
Return M_NSubdircount-1;
}
protected:
/ / Overwrite the virtual function processfile, each call once, the number of files plus 1
Virtual Bool ProcessFile (const char * filename)
{
m_nfilecount ;
Return CBROWSEDIR :: ProcessFile (filename);
}
/ / Overwrite the virtual function ProcessDir, each call once, the number of subdirectory plus 1
Virtual void ProcessDir
Const Char * Currentdir, Const Char * Parentdir
{
m_nsubdircount ;
CBROWSEDIR :: ProcessDir (curRentdir, Parentdir);
}
void main ()
{
// Get a directory name
Char BUF [256];
Printf ("Please enter the directory name you want to count:");
Gets (buf);
// Configuration class object
CSTATDIR Statdir;
/ / Set the directory to be traversed
IF (! statdir.setinitdir (buf))
{
PUTS ("The directory does not exist.");
Return;
}
// Start traversing
Statdir.Beginbrowse ("*. *");
// In the statistical result, the number of subdirectory is not included.
Printf ("Total number of files:% D / N subdirectory total:
% D / N ", Statdir.GetFileCount (),
Statdir.getsubdircount ());
}