【问题标题】:Listing directory contents using C and Windows使用 C 和 Windows 列出目录内容
【发布时间】:2011-01-19 20:22:52
【问题描述】:

我希望在 Windows 上使用 C 列出目录的内容并将其存储在结构中。

我不一定要找人写出我正在寻找的代码,而是在我应该查看哪个库时为我指明正确的方向。

我已经在谷歌上搜索了几个小时,我发现的只是 C#、C++ 解决方案,因此我们将不胜感激。

【问题讨论】:

  • 您的 C++ 解决方案将向您展示您需要进行哪些 API 调用。

标签: c windows directory-structure


【解决方案1】:

就像其他人所说的(使用 FindFirstFile、FindNextFile 和 FindClose)...但使用递归!

bool ListDirectoryContents(const char *sDir)
{
    WIN32_FIND_DATA fdFile;
    HANDLE hFind = NULL;

    char sPath[2048];

    //Specify a file mask. *.* = We want everything!
    sprintf(sPath, "%s\\*.*", sDir);

    if((hFind = FindFirstFile(sPath, &fdFile)) == INVALID_HANDLE_VALUE)
    {
        printf("Path not found: [%s]\n", sDir);
        return false;
    }

    do
    {
        //Find first file will always return "."
        //    and ".." as the first two directories.
        if(strcmp(fdFile.cFileName, ".") != 0
                && strcmp(fdFile.cFileName, "..") != 0)
        {
            //Build up our file path using the passed in
            //  [sDir] and the file/foldername we just found:
            sprintf(sPath, "%s\\%s", sDir, fdFile.cFileName);

            //Is the entity a File or Folder?
            if(fdFile.dwFileAttributes &FILE_ATTRIBUTE_DIRECTORY)
            {
                printf("Directory: %s\n", sPath);
                ListDirectoryContents(sPath); //Recursion, I love it!
            }
            else{
                printf("File: %s\n", sPath);
            }
        }
    }
    while(FindNextFile(hFind, &fdFile)); //Find the next file.

    FindClose(hFind); //Always, Always, clean things up!

    return true;
}

ListDirectoryContents("C:\\Windows\\");

现在是它的 UNICODE 对应物:

bool ListDirectoryContents(const wchar_t *sDir)
{ 
    WIN32_FIND_DATA fdFile; 
    HANDLE hFind = NULL; 

    wchar_t sPath[2048]; 

    //Specify a file mask. *.* = We want everything! 
    wsprintf(sPath, L"%s\\*.*", sDir); 

    if((hFind = FindFirstFile(sPath, &fdFile)) == INVALID_HANDLE_VALUE) 
    { 
        wprintf(L"Path not found: [%s]\n", sDir); 
        return false; 
    } 

    do
    { 
        //Find first file will always return "."
        //    and ".." as the first two directories. 
        if(wcscmp(fdFile.cFileName, L".") != 0
                && wcscmp(fdFile.cFileName, L"..") != 0) 
        { 
            //Build up our file path using the passed in 
            //  [sDir] and the file/foldername we just found: 
            wsprintf(sPath, L"%s\\%s", sDir, fdFile.cFileName); 

            //Is the entity a File or Folder? 
            if(fdFile.dwFileAttributes &FILE_ATTRIBUTE_DIRECTORY) 
            { 
                wprintf(L"Directory: %s\n", sPath); 
                ListDirectoryContents(sPath); //Recursion, I love it! 
            } 
            else{ 
                wprintf(L"File: %s\n", sPath); 
            } 
        }
    } 
    while(FindNextFile(hFind, &fdFile)); //Find the next file. 

    FindClose(hFind); //Always, Always, clean things up! 

    return true; 
} 

ListDirectoryContents(L"C:\\Windows\\");

【讨论】:

  • 第一个例子 - 你需要 stdio.hwindows.h 否则可以通过 g++ 编译,没有问题并且 works :)
  • 我遇到了问题。当我试图列出名称以 cp1386(简体中文)编码的文件时,我的 win7 使用 cp950(繁体中文)作为其原生编码。 FindFirstFile/FindNextFile 总是尝试将它们转码为本机编码,问题是它们无法用于打开文件。有什么办法可以禁止吗?我用mingw。
  • 等待;所以 Windows API 只允许一次查看一个文件的目录?有没有办法在一次调用中获取所有当前目录数据? O.o
  • @Dmitry 您可以创建一个封装枚举的函数,并让它为每个文件路径返回一个字符串数组。一般来说,枚举一个小目录根本不需要很长时间——但对于一个深层结构来说可能需要相当长的时间。因此,如果您选择“一次调用”方法 - 请务必编写一些进度报告。
【解决方案2】:

您可能正在寻找这些函数:FindFirstFileFindNextFileFindClose

【讨论】:

    【解决方案3】:

    要列出文件内容,您可以使用以下 API 搜索目录:FindFirstFileExFindNextFileCloseFind。您需要#include <windows.h>,这将使您能够访问 Windows API。它们是 C 函数,因此与 C++ 兼容。如果您想要“特别是 C++”,请尝试使用 MFC 搜索列表目录。

    【讨论】:

    • 他在使用 MFC 吗? (这是魔鬼!)
    • 我不知道。我也不是粉丝,但它确实让你对事物有一个 OO 的看法。
    猜你喜欢
    • 1970-01-01
    • 2019-09-05
    • 1970-01-01
    • 2011-03-18
    • 1970-01-01
    • 2012-01-31
    • 2011-07-14
    • 2015-05-24
    • 2011-02-28
    相关资源
    最近更新 更多