如何在 Windows 上递归遍历 C 中的目录

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2038912/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-15 13:43:31  来源:igfitidea点击:

How to recursively traverse directories in C on Windows

cwindowswinapifilesystems

提问by pmilb

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?

最终,我想遍历文件夹的文件和子目录,并向我发现具有特定扩展名的所有文件写入一些内容(在我的情况下为 .wav)。循环时如何判断我所在的项目是否是目录?

回答by Luke

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.

在 C:\WINDOWS 及其子目录中查找所有 *.wav 文件。

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.

从技术上讲,您不必执行两次 FindFirstFile() 调用,但我发现 Microsoft 提供的模式匹配函数(即 PathMatchFileSpec 或其他)不如 FindFirstFile() 功能强大。虽然对于“*.wav”来说可能没问题。

回答by Jerry Coffin

Based on your mention of .wav, I'm going to guess you're writing code for Windows (that seems to be where *.wavfiles are most common). In this case, you use FindFirstFileand FindNextFileto traverse directories. These use a WIN32_FIND_DATAstructure, which has a member dwFileAttributesthat contains flags telling the attributes of the file. If dwAttributes & FILE_ATTRIBUTE_DIRECTORYis non-zero, you have the name of a directory.

根据您提到的.wav,我猜您正在为 Windows 编写代码(这似乎是*.wav文件最常见的地方)。在这种情况下,您使用FindFirstFileFindNextFile来遍历目录。它们使用一个WIN32_FIND_DATA结构,该结构具有一个成员dwFileAttributes,该成员包含告诉文件属性的标志。如果dwAttributes & FILE_ATTRIBUTE_DIRECTORY不为零,则您具有目录的名称。

回答by motiwert

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;

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

回答by jspcal

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

opendir 和 readdir(在 unix 上),这是一个例子:

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

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

or FindFirstFile on windows

或 Windows 上的 FindFirstFile

you could also use the shell pretty easily:

你也可以很容易地使用 shell:

find . -name "*.wav"

or

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