使用递归来获取某个目录中的所有文件

时间:2012-10-15 15:40:12

标签: c++ winapi

我尝试编写应用程序,查找当前diretory及其子目录中的所有文件。我有下一个问题,我无法完全理解

  1. 我需要在我的案例中使用递归GetFiles()函数,
  2. 我需要在PathCreator()函数中动态分配的空闲内存。当我仅针对某个目录(没有子目录)测试此程序时,它可以工作(在_tmain()中查看已注释的代码)。但是当我试图获取所有文件时会崩溃。
  3. 这是我的代码:

    // ConsoleApplication1.cpp : Defines the entry point for the console application.
    //
    
    #include "stdafx.h"
    #include <windows.h>
    #include <iostream>
    #define SIZE 300
    
    int is_directory(wchar_t *p)
    {
        wchar_t temp[300];
        int i;
        i = 0;
        while(*p != '\0')
        {
            temp[i] = *p;
            p++;
            i++;
        }
        temp[i] = '\\';
        i++;
        temp[i] = '\0';
        WIN32_FIND_DATA file;
        HANDLE search_hendle = FindFirstFile(temp, &file);
        long error = GetLastError();
        if(error == 267)
        {
            return 0;
        }
        else
        {
            return 1;
        }
    }
    
    
    wchar_t *PathCreator(wchar_t *dir, wchar_t *fileName)
    {
        wchar_t* path = new wchar_t[SIZE];
        int j = 0;
        while(j < SIZE)
        {
            path[j] = '\0';
            j++;
        }
        int i;
        i = 0;
        while(*dir != '*' && *dir != '\0')
        {
            path[i] = *dir;
            i++;
            dir++;
        }
        wchar_t *t = fileName;  
        while(*t != '\0')
        {
            path[i] = *t;
            i++;
            t++;
        }
        path[i] = '\0';
        return path;
    } 
    
    wchar_t* allFlsArr[SIZE];
    int i = 0;
    wchar_t **GetAllFiles(wchar_t* dir)
    {
        WIN32_FIND_DATA file;
        HANDLE search_hendle = FindFirstFile(dir, &file);
        if(search_hendle)
        {
            do
            {
                wchar_t *p = PathCreator(dir,file.cFileName);
                allFlsArr[i++] = p;
            }
            while(FindNextFile(search_hendle, &file));
            allFlsArr[i] = '\0';
        }
        CloseHandle(search_hendle);
        return allFlsArr;
    }
    
    void GetFiles(wchar_t *dir)
    {
        wchar_t **filePaths = 0;
        filePaths = GetAllFiles(dir);
        int  i = 0;
        while(filePaths[i] != '\0'){
            if(!is_directory(filePaths[i]))
            {
                std::wcout << filePaths[i] << std::endl;
            }
            else
            {
                GetAllFiles(filePaths[i]);
            }
        }
        delete [] filePaths;
    }
    int _tmain(int argc, _TCHAR* argv[])
    {
        /*wchar_t **wch = GetAllFiles(L"C:\\*");
        int i = 0;
        while( *wch != '\0')
        {
            std::wcout << *wch << std::endl;
            wch++;
        }*/
        GetFiles(L"C:\\*");
    }
    

1 个答案:

答案 0 :(得分:2)

首先我想知道为什么你永远不会使用像wcscpywcscat或...这样的函数,并且总是手工执行所有字符串和缓冲区操作!但除此之外,您的代码中存在一些问题:

  • 您使用单个宽字符串指针数组(allFlsArr)将GetAllFiles的结果返回给调用者,当您迭代该结果时,您将再次调用GetAllFiles这将覆盖allFlsArr

  • 您正在使用GetAllFiles释放delete[] filePaths的结果,但实际上allFlsArr是全局变量且无法删除。尝试不需要std::vector<std::wstring>的{​​{1}}。

  • 您的文件名数组太小,无法接受文件夹中包含300个以上文件或文件夹的文件,请再次尝试delete/new,其大小可以增加并接受任意数量的项目!

  • 使用std::vector<std::wstring>搜索文件夹时,Windows会返回到您永远不应搜索的额外目录(*.)。你应该跳过它们(..

  • 当您使用if(!wcscmp(file.cFileName, L".") || !wcscmp(file.cFileName, L"..")) continue时,使用CloseHandle关闭从FindFirstFile返回的句柄。

所以你可能有这样的事情:

FindClose