How to recursively traverse directories in C on Wi

2019-01-18 06:59发布

问题:

Ultimately I want to travel through a folder's files and subdirectories and write something to all files i find that have a certain extension(.wav in my case). when looping how do i tell if the item I am at is a directory?

回答1:

Here is how you do it (this is all from memory so there may be errors):

void FindFilesRecursively(LPCTSTR lpFolder, LPCTSTR lpFilePattern)
{
    TCHAR szFullPattern[MAX_PATH];
    WIN32_FIND_DATA FindFileData;
    HANDLE hFindFile;
    // first we are going to process any subdirectories
    PathCombine(szFullPattern, lpFolder, _T("*"));
    hFindFile = FindFirstFile(szFullPattern, &FindFileData);
    if(hFindFile != INVALID_HANDLE_VALUE)
    {
        do
        {
            if(FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
            {
                // found a subdirectory; recurse into it
                PathCombine(szFullPattern, lpFolder, FindFileData.cFileName);
                FindFilesRecursively(szFullPattern, lpFilePattern);
            }
        } while(FindNextFile(hFindFile, &FindFileData));
        FindClose(hFindFile);
    }

    // Now we are going to look for the matching files
    PathCombine(szFullPattern, lpFolder, lpFilePattern);
    hFindFile = FindFirstFile(szFullPattern, &FindFileData);
    if(hFindFile != INVALID_HANDLE_VALUE)
    {
        do
        {
            if(!(FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
            {
                // found a file; do something with it
                PathCombine(szFullPattern, lpFolder, FindFileData.cFileName);
                _tprintf_s(_T("%s\n"), szFullPattern);
            }
        } while(FindNextFile(hFindFile, &FindFileData));
        FindClose(hFindFile);
    }
}

So you could call this like

FindFilesRecursively(_T("C:\\WINDOWS"), _T("*.wav"));

to find all the *.wav files in C:\WINDOWS and its subdirectories.

Technically you don't have to do two FindFirstFile() calls, but I find the pattern matching functions Microsoft provides (i.e. PathMatchFileSpec or whatever) aren't as capable as FindFirstFile(). Though for "*.wav" it would probably be fine.



回答2:

Based on your mention of .wav, I'm going to guess you're writing code for Windows (that seems to be where *.wav files are most common). In this case, you use FindFirstFile and FindNextFile to traverse directories. These use a WIN32_FIND_DATA structure, which has a member dwFileAttributes that contains flags telling the attributes of the file. If dwAttributes & FILE_ATTRIBUTE_DIRECTORY is non-zero, you have the name of a directory.



回答3:

Very Helpful. I had anyway, a stack overflow since it was always adding "." to the path and returning to the same path = endless loop.

Adding this solved it:

// found a subdirectory; recurse into it PathCombine(szFullPattern, lpFolder, FindFileData.cFileName); FindFilesRecursively(szFullPattern, lpPattern); if (FindFileData.cFileName[0] == '.') continue;



回答4:

opendir and readdir (on unix), here's an example:

http://opengroup.org/onlinepubs/007908775/xsh/readdir.html

or FindFirstFile on windows

you could also use the shell pretty easily:

find . -name "*.wav"

or

ls **/*.wav    (in zsh and newer bashes)


回答5:

check these links

  1. http://msdn.microsoft.com/en-us/library/aa365522(VS.85).aspx
  2. http://www.codeguru.com/forum/showthread.php?t=312461