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

Using recursion to get all files in some directory

本文关键字:文件 递归 获取      更新时间:2023-10-16

我试图编写一个应用程序,在当前目录及其子目录中查找所有文件。我有下一个问题我不能完全理解

  1. 在我的情况下,我需要如何使用递归GetFiles()函数,以及
  2. 我需要在PathCreator()函数中动态分配的空闲内存。当我只为某个目录(没有子目录)测试这个程序时,它可以工作(在_tmain()中查看注释代码)。但当我试图获取所有文件时,就会崩溃

这是我的代码:

// 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 != '')
{
temp[i] = *p;
p++;
i++;
}
temp[i] = '';
i++;
temp[i] = '';
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] = '';
j++;
}
int i;
i = 0;
while(*dir != '*' && *dir != '')
{
path[i] = *dir;
i++;
dir++;
}
wchar_t *t = fileName;  
while(*t != '')
{
path[i] = *t;
i++;
t++;
}
path[i] = '';
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] = '';
}
CloseHandle(search_hendle);
return allFlsArr;
}
void GetFiles(wchar_t *dir)
{
wchar_t **filePaths = 0;
filePaths = GetAllFiles(dir);
int  i = 0;
while(filePaths[i] != ''){
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 != '')
{
std::wcout << *wch << std::endl;
wch++;
}*/
GetFiles(L"C:\*");
}

首先,我想知道为什么从不使用wcscpywcscat或。。。并且总是手动操作所有字符串和缓冲区!?但除此之外,你的代码中还有一些问题:

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

  • 您正在使用delete[] filePaths释放GetAllFiles的结果,但这实际上是allFlsArr,它是一个全局变量,不能删除。尝试不需要delete/newstd::vector<std::wstring>

  • 您的文件名数组太小,无法接受文件夹中超过300个文件或文件夹的文件,请再次尝试std::vector<std::wstring>,它可以扩大大小并接受任何数量的项目!

  • 当您使用*搜索文件夹时,Windows会返回到不应该搜索它们的额外目录(...)。你应该跳过它们(if(!wcscmp(file.cFileName, L".") || !wcscmp(file.cFileName, L"..")) continue)

  • 使用CloseHandle关闭从FindFirstFile返回的句柄,而应该使用FindClose

所以你可能有这样的东西:

std::vector<std::wstring> list_files( wchar_t const* folder )
{
std::wstring root = folder;
if( folder.back() == '*' ) folder.erase( folder.end() - 1 );
if( folder.back() != '' ) folder.push_back( '' );
std::vector<std::wstring> res;
WIN32_FIND_DATA file;
HANDLE hSearch = FindFirstFileW( folder, &file );
if( hSearch != INVALID_HANDLE_VALUE ) {
do {
if( !wcscmp(file.cFileName, L".") ||
!wcscmp(file.cFileName, L"..") )
continue;
res.push_back( root + file.cFileName );
if( file.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ) {
// search for sub folders of this folder
std::vector<std::wstring> tmp =
list_files( (root + file.cFileName) + L"\*" );
// all all items to end of our result!
res.insert( res.end(), tmp.begin(), tmp.end() );
}
} while( FindNextFileW(hSearch, &file) );
FindClose( hSearch );
}
return res;
}