Click here to Skip to main content
6,595,854 members and growing! (17,347 online)
Email Password   helpLost your password?
Desktop Development » Files and Folders » Utilities     Intermediate License: The Code Project Open License (CPOL)

Directory file listing utility

By Shup

An article on recursively listing all files in a given directory.
C++, Windows, WinMobile5, WinMobile6, Win32, VS2005, VS2008, Dev
Version:10 (See All)
Posted:14 Jan 2009
Views:7,803
Bookmarked:13 times
Announcements
Loading...
 
Search    
Advanced Search
Add to IE Search
printPrint   add Share
      Discuss Discuss   Broken Article?Report  
10 votes for this article.
Popularity: 3.22 Rating: 3.22 out of 5
2 votes, 20.0%
1

2
4 votes, 40.0%
3
1 vote, 10.0%
4
3 votes, 30.0%
5

Introduction

I’ve come across countless situations where routinely used utilitarian functions are simply not available, and coders simply have to write and rewrite them many times over. This is my first article in a series of articles which will try to provide a collection of routinely used functions with example applications on how to use them, in the hope that they will be as useful to the many developers out there as it has been to me.

One such function is to obtain a list of all files (their absolute paths) given a directory to start with, with options to search recursively into sub-directories or just to output the files present directly under the given directory.

I’ve found this to be extremely useful in many projects which required going through each file for some reason or the other.

Background

This function was developed many years ago when I stumbled upon a barrage of projects that required reading into every file in a given directory, and also provide progress information in real time, e.g., which file is being currently processed, total number of files, and number of files already processed. Since then, I’ve probably used this function in a few dozen projects.

Using the Code

Follow these simple steps to use the code in your project:

  1. Add the files Util.h and Util.cpp into your Visual Studio C++ project (or any other kind of project, I have never used the code on anything other than Visual Studio C++ projects, so any input on using it on other C++ projects is appreciated).
  2. Add the line #include “Util.h” in the top section of the *.cpp files you intend to use this function in.
  3. Declare a vector of stlStrings: vector<stlString> vecstrFileList;.
  4. Call the static function "GetFileList()" with the required parameters.
  5. The vector will now have all the file paths found in the directory specified, each element of the vector being a string representing the absolute path of a file. Note that you must explicitly clear the vector before reusing it, unless you want the function to append to the vector. The function will also work on network drive directory paths.
  6. Take a look at the "Get file list" button event handler function in the source code to see steps 1 to 5 in action.
  7. Check the "Util.cpp" source file, or the code snippet below, for a detailed description of how the function is working internally, it is extensively commented.
void CUtil::GetFileList(const stlString& strTargetDirectory, 
     bool bLookInSubdirectories, vector<stlstring>& vecstrFileList)
{
    // Check whether target directory string is empty
    if(strTargetDirectory.compare(_T("")) == 0)
    {
        return;
    }

    // Remove "\\" if present at the end of the target directory
    // Then make a copy of it and use as the current search directory
    stlString strCurrentDirectory = RemoveDirectoryEnding(strTargetDirectory);

    // This data structure stores information about the file/folder
    // that is found by any of these Win32 API functions:
    // FindFirstFile, FindFirstFileEx, or FindNextFile function
    WIN32_FIND_DATA fdDesktop = {0};

    // Check which character set is being used and allocate array of required type
#ifdef UNICODE
    wchar_t strDesktopPath[_MAX_PATH];
#else
    char strDesktopPath[_MAX_PATH];
#endif

    // Format and copy the current directory to the character array
    // Note the addition of the wildcard *.*, which represents all files
    // 
    // Below is a list of wildcards that you can use
    // * (asterisk)            - represents zero or more characters
    //                        at the current character position
    // ? (question mark)    - represents a single character
    //
    // Modify this function so that the function can take in a search pattern
    // with wildcards and use it in the line below to find for e.g. only *.mpg files
    _stprintf_s(strDesktopPath, _MAX_PATH, _T("%s\\*.*"), strCurrentDirectory.c_str());

    // Finds the first file and populates
    // the WIN32_FIND_DATA data structure with its information
    // The return value is a search handle used in subsequent calls
    // to FindNextFile or FindClose functions
    HANDLE hDesktop = ::FindFirstFile(strDesktopPath, &fdDesktop);    

    // If an invalid handle is returned by FindFirstFile function,
    // something went wrong, so just quit
    if(hDesktop == INVALID_HANDLE_VALUE)
    {
        return;
    }

    // Do this on the first file found and repeat for every next
    // file found until all the required files that match the search pattern are found
    do 
    {
        // Check if a directory was found
        if(fdDesktop.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
        {
            // Reconstruct the directory path
            _stprintf_s(strDesktopPath, _MAX_PATH, _T("%s\\%s"), 
                        strCurrentDirectory.c_str(), fdDesktop.cFileName);
            
            // Get the name of the directory
            stlString strCurrentDirectoryName = GetDirectoryName(strDesktopPath);

            // If its a current (.) or previous (..) directory indicator, just skip it
            if((strCurrentDirectoryName.compare(_T(".")) == 0) || 
               (strCurrentDirectoryName.compare(_T("..")) == 0))
            {
                continue;
            }
            // Other wise this is a sub-directory
            else
            {
                // Check whether function was called
                // to include sub-directories in the search
                if(bLookInSubdirectories)
                {
                    // If sub-directories are to be searched as well, recursively
                    // call the function again,
                    // with the target directory as the sub-directory
                    GetFileList(strDesktopPath, bLookInSubdirectories, vecstrFileList);
                }
            }
        }
        // A file was found
        else
        // if(fdDesktop.dwFileAttributes & FILE_ATTRIBUTE_NORMAL)
        {
            // Reconstruct the file path
            _stprintf_s(strDesktopPath, _MAX_PATH, _T("%s\\%s"), 
                        strCurrentDirectory.c_str(), fdDesktop.cFileName);
            
            // Create a stlString for the file path
            stlString strFilePath = strDesktopPath;
            
            // Add the string to the vector
            vecstrFileList.push_back(strFilePath);
        }
    }
    // Search for the next file that matches the search pattern
    while(::FindNextFile(hDesktop, &fdDesktop) == TRUE);

    // Close the search handle
    ::FindClose(hDesktop);
}

Points of Interest

The code provided here is for unmanaged C++; if you are using managed code or C#, which uses the .NET Framework, you can use the Directory.GetFiles methods; you can read about it here.

While writing this code, I found that, to my annoyance, Microsoft Windows does not have any easy to use unmanaged C++ code to actually do this in a straightforward and simple manner. If you do find this code useful, please leave a comment, it could make my day :-)

History

  • V1.0 - Initial release.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

Shup


Member
(AKA The Freak), besides being a computer geek, given his love for extreme sports, is a fire spinner, sky diver, and a XC/DH biker. He juggles his time between being a business man, computer scientist, a researcher in robotics, and many other bizarre hobbies.
Occupation: Chief Technology Officer
Company: Mind & Machines
Location: Bangladesh Bangladesh

Other popular Files and Folders articles:

Article Top
You must Sign In to use this message board.
FAQ FAQ 
 
Noise Tolerance  Layout  Per page   
 Msgs 1 to 17 of 17 (Total in Forum: 17) (Refresh)FirstPrevNext
GeneralExcellent PinmemberSharjith18:01 11 Mar '09  
GeneralRe: Excellent PinmemberShup18:10 11 Mar '09  
GeneralRe: Excellent PinmemberSharjith2:48 13 Mar '09  
QuestionCompile error PinmemberSaffarian22:36 31 Jan '09  
GeneralEncouragement Pinmemberloreia22:52 16 Jan '09  
GeneralRe: Encouragement PinmemberShup2:32 17 Jan '09  
GeneralRe: Encouragement Pinmemberloreia3:14 17 Jan '09  
GeneralRe: Encouragement PinmemberShup3:24 17 Jan '09  
GeneralRe: Encouragement Pinmemberloreia5:21 17 Jan '09  
GeneralRe: Encouragement PinmemberShup5:00 20 Jan '09  
GeneralRe: Encouragement Pinmemberloreia21:25 20 Jan '09  
GeneralSilly PinmemberMrBobIsMean9:19 16 Jan '09  
GeneralRe: Silly PinmemberShup16:47 16 Jan '09  
GeneralMy vote of 1 PinmemberMustafa J0:07 15 Jan '09  
GeneralRe: My vote of 1 PinmemberShup0:39 15 Jan '09  
GeneralMy vote of 1 PinmemberAlexandre GRANVAUD23:09 14 Jan '09  
GeneralRe: My vote of 1 PinmemberShup0:46 15 Jan '09  

General General    News News    Question Question    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

PermaLink | Privacy | Terms of Use
Last Updated: 14 Jan 2009
Editor: Smitha Vijayan
Copyright 2009 by Shup
Everything else Copyright © CodeProject, 1999-2009
Web16 | Advertise on the Code Project