Click here to Skip to main content
13,866,049 members
Click here to Skip to main content
Add your own
alternative version


38 bookmarked
Posted 14 Jan 2009
Licenced CPOL

Directory file listing utility

, 13 Jun 2012
Rate this:
Please Sign up or sign in to vote.
An article about methods to recursively list all files in a given directory.


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.


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 _tstring's: vector <_tstring> 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 _tstring& strTargetDirectoryPath, 
     const _tstring& strWildCard, bool bLookInSubdirectories, 
     vector<_tstring>& vecstrFileList)
    // Check whether target directory string is empty
    if("")) == 0)

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

    // 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};

    // Format and copy the current directory
    // 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
    // "\\?\" prefix to the file path means that the
    // file system supports large paths/filenames
    _tstring strDesktopPath = _T("");
    strDesktopPath += _T("\\\\?\\");
    strDesktopPath += strCurrentDirectory;
    strDesktopPath = AddDirectoryEnding(strDesktopPath);

    if("")) == 0)
        strDesktopPath += _T("*.*");
        strDesktopPath += strWildCard;

    // 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.c_str(), &fdDesktop);    

    // If an invalid handle is returned by FindFirstFile function,
    // then the directory is empty, so nothing to do but quit
    if(hDesktop == INVALID_HANDLE_VALUE)

    // 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
        // Reconstruct the path
        _tstring strPath = _T("");
        strPath += strCurrentDirectory;
        strPath = AddDirectoryEnding(strPath);
        strPath += fdDesktop.cFileName;

        // Check if a directory was found
        if(fdDesktop.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
            // Get the name of the directory
            _tstring strCurrentDirectoryName = GetDirectoryName(strPath);

            // If its a current (.) or previous (..)
            // directory indicator, just skip it
            if((".")) == 0) || 
               ("..")) == 0))
            // Other wise this is a sub-directory
                // Check whether function was called
                // to include sub-directories in the search
                    // If sub-directories are to be searched as well,
                    // recursively call the function again,
                    // with the target directory as the sub-directory
                    GetFileList(strPath, strWildCard, bLookInSubdirectories, 
        // A file was found
        // if(fdDesktop.dwFileAttributes & FILE_ATTRIBUTE_NORMAL)
            // Add the string to the vector
    // Search for the next file that matches the search pattern
    while(::FindNextFile(hDesktop, &fdDesktop) == TRUE);

    // Close the search handle

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 Smile | :)

Known Issues

When recursively finding files in sub-directories using a wild card, if the parent directory does not have at least one such file, the nested directories will not be searched.


  • V1.0 - Initial release.
  • V1.1 - Fixed recursive sub-directory search.


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


About the Author

Chief Technology Officer Mind & Machines
Bangladesh Bangladesh
(AKA The Freak), besides being a computer nerd, given his love for extreme sports, is a fire spinner, sky diver, and a XC/DH biker. He juggles his time between computing, research, business, travelling, gourmet cooking, and many other bizarre hobbies.

You may also be interested in...

Comments and Discussions

QuestionIs it possible to do this in Visual Studio Express 2015 - C++? Pin
Member 1186689310-Sep-15 5:16
memberMember 1186689310-Sep-15 5:16 
AnswerRe: Is it possible to do this in Visual Studio Express 2015 - C++? Pin
Shup7-Dec-15 3:04
memberShup7-Dec-15 3:04 
QuestionSimple but very useful Pin
xuanle7-Aug-13 18:38
memberxuanle7-Aug-13 18:38 
GeneralMy vote of 1 Pin
ozbear18-Jun-12 14:57
memberozbear18-Jun-12 14:57 
GeneralRe: My vote of 1 Pin
Shup21-May-13 6:14
memberShup21-May-13 6:14 
GeneralRe: My vote of 1 Pin
ozbear21-May-13 12:05
memberozbear21-May-13 12:05 
GeneralRe: My vote of 1 Pin
Shup21-May-13 14:09
memberShup21-May-13 14:09 
GeneralMy vote of 2 Pin
Howard Richards15-Jun-12 0:32
memberHoward Richards15-Jun-12 0:32 
GeneralRe: My vote of 2 Pin
Shup21-May-13 6:15
memberShup21-May-13 6:15 
Question[My vote of 2] Wouldn't a line command do the trick ? Pin
mullerhe21-Dec-11 12:24
membermullerhe21-Dec-11 12:24 
AnswerRe: [My vote of 2] Wouldn't a line command do the trick ? Pin
Haseeb Baber21-Dec-11 23:50
memberHaseeb Baber21-Dec-11 23:50 
AnswerRe: [My vote of 2] Wouldn't a line command do the trick ? Pin
Shup23-Dec-11 12:56
memberShup23-Dec-11 12:56 
GeneralRe: [My vote of 2] Wouldn't a line command do the trick ? Pin
mullerhe23-Dec-11 13:25
membermullerhe23-Dec-11 13:25 
GeneralRe: [My vote of 2] Wouldn't a line command do the trick ? Pin
Shup23-Dec-11 20:14
memberShup23-Dec-11 20:14 
GeneralRe: [My vote of 2] Wouldn't a line command do the trick ? Pin
mullerhe23-Dec-11 22:59
membermullerhe23-Dec-11 22:59 
Questionbasic but not bad Pin
BillW3316-Dec-11 11:30
professionalBillW3316-Dec-11 11:30 
AnswerRe: basic but not bad Pin
Shup16-Dec-11 11:34
memberShup16-Dec-11 11:34 
GeneralRe: basic but not bad Pin
BillW3316-Dec-11 11:57
professionalBillW3316-Dec-11 11:57 
GeneralMy vote of 1 PinPopular
jeffb4216-Dec-11 7:49
memberjeffb4216-Dec-11 7:49 
GeneralRe: My vote of 1 Pin
Shup16-Dec-11 8:48
memberShup16-Dec-11 8:48 
GeneralRe: My vote of 1 Pin
Haseeb Baber21-Dec-11 23:53
memberHaseeb Baber21-Dec-11 23:53 
GeneralRe: My vote of 1 Pin
Shup23-Dec-11 12:56
memberShup23-Dec-11 12:56 
Questionunable to get results on *.txt Pin
Haseeb Baber15-Dec-11 1:21
memberHaseeb Baber15-Dec-11 1:21 
AnswerRe: unable to get results on *.txt Pin
Shup15-Dec-11 1:53
memberShup15-Dec-11 1:53 
AnswerRe: unable to get results on *.txt Pin
Shup15-Dec-11 3:46
memberShup15-Dec-11 3:46 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Permalink | Advertise | Privacy | Cookies | Terms of Use | Mobile
Web06 | 2.8.190214.1 | Last Updated 13 Jun 2012
Article Copyright 2009 by Shup
Everything else Copyright © CodeProject, 1999-2019
Layout: fixed | fluid