【问题标题】:print all files and subdirectories in a give path打印给定路径中的所有文件和子目录
【发布时间】:2014-11-09 18:08:34
【问题描述】:

所以,我正在编写一个程序来递归打印给定路径中的目录/子目录和文件。我能够进入第一个子目录并打印其中的所有文件。我现在的问题是我需要找到一种方法来退回一个目录级别并从我停止阅读的地方继续。直到条件发生在原始目录级别。

#include "Everything.h"
#include "Strsafe.h"

WIN32_FIND_DATA ffd;
HANDLE          hFind = INVALID_HANDLE_VALUE;
LARGE_INTEGER   fileSize;
DWORD           dwError;

void showdir(TCHAR *szDir);

int _tmain(int argc, LPCTSTR argv[])
{


    TCHAR           szDir[MAX_PATH];
    size_t          lengthOfArg;

    // verify number of parameters
    if (argc != 2)
    {
        ReportError(_T("Error: Incorrect number of arguments"), 1, FALSE);
    }

    // get the length of the entered directory
    StringCchLength(argv[1], MAX_PATH, &lengthOfArg);

    // verify that the directory path is not too long
    if (lengthOfArg > MAX_PATH - 2)
    {
        ReportError(_T("Error: Directory too long"), 2, FALSE);
    }

    // attach an asterisk (wildcard search char) to end of directory path
    StringCchCopy(szDir, MAX_PATH, argv[1]);
    StringCchCat(szDir, MAX_PATH, _T("*"));

    showdir(szDir);
}

void showdir(TCHAR *szDir)
{
    // begin the search; find the first file in the directory
    hFind = FindFirstFile(szDir, &ffd);
    if (hFind == INVALID_HANDLE_VALUE)
    {
        ReportError(_T("Error in searching"), 3, TRUE);
    }

    //hFind = FindFirstFile(szDir, &ffd);
    while (FindNextFile(hFind, &ffd) != 0)
    {
        if ((ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0)
        {
            fileSize.LowPart = ffd.nFileSizeLow;
            fileSize.HighPart = ffd.nFileSizeHigh;
            _tprintf(_T("%s   %ld\n"), ffd.cFileName, fileSize.QuadPart);

        }       

        // did we find a directory?
        // ffd.dwFileAttributes says this is a directory (FILE_ATTRIBUTE_DIRECTORY)

        if ((ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) 
            && (_tcscmp(ffd.cFileName, _T(".")) != 0 && (_tcscmp(ffd.cFileName, _T("..")) != 0)))
        {
            TCHAR fullpath[MAX_PATH];

            StringCchCopy(fullpath, strlen(szDir) - 0, szDir);
            StringCchCat(fullpath, MAX_PATH, ffd.cFileName);
            StringCchCat(fullpath, MAX_PATH, "\\");
            _tprintf(_T("<DIR>  %s \n"), fullpath);
            StringCchCat(fullpath, MAX_PATH, _T("*"));



            showdir(fullpath);

        }   
        // continue the search; try to find more files
    } 

    // figure out if we encountered an error other than "no more files"
    dwError = GetLastError();

    if (dwError != ERROR_NO_MORE_FILES)
    {
        ReportError(_T("Error in searching"), 4, TRUE);
    }

    FindClose(hFind);

}

【问题讨论】:

    标签: c windows recursion


    【解决方案1】:

    你的全局变量

    WIN32_FIND_DATA ffd;
    HANDLE          hFind = INVALID_HANDLE_VALUE;
    LARGE_INTEGER   fileSize;
    DWORD           dwError;
    

    都应该是showdir()局部变量。 然后每个递归级别都有自己的搜索句柄,当嵌套showdir() 返回,调用showdir() 可以简单地继续枚举其目录。

    另请注意,您的代码会忽略每个目录中的第一个文件(结果 FindFirstFile())。您可以将其重写为(为简洁起见省略了错误检查):

    hFind = FindFirstFile(szDir, &ffd);
    do {
    
        // ... handle ffd ...
    
    } while (FindNextFile(hFind, &ffd))
    

    【讨论】:

    • 在递归之前将整个目录详细信息读入数组或链表。然后,您可以更轻松地从上次中断的地方继续。
    • @WeatherVane:当然,这也是一个可能的解决方案。在任何情况下,状态信息(WIN32_FIND_DATA 或数组 + 当前索引)必须是函数本地的。
    猜你喜欢
    • 2017-04-03
    • 2016-08-17
    • 1970-01-01
    • 2021-03-26
    • 2016-05-16
    • 1970-01-01
    • 1970-01-01
    • 2017-03-15
    • 1970-01-01
    相关资源
    最近更新 更多