Empty Directory Enumeration

01/29/2014 15:12 XxharCs#1
Hallo!

Ich enumiere alle Ordner eines Pfads bzw. eines Datenträgers und suche nach leeren Ordnern.

Soweit so gut, hab ichs geschafft, wollte aber fragen ob ich die rekursion besser gestalten kann, weil ich so ein Gefühl habe, dass man es sicher besser machen kann :D

Danke in vorraus!

Code:
int searchEmptyDirs(vector<string> &storedFiles, const string &startDir)
{
	string strFilePath;
	string strPattern;
	HANDLE hFile;
	WIN32_FIND_DATA fileInformation;
	
	strPattern = startDir + "\\*.*";
	hFile = FindFirstFileA(strPattern.c_str(), &fileInformation);

	if(hFile != INVALID_HANDLE_VALUE)
	{
		do
		{
			if(fileInformation.cFileName[0] != '.')
			{
				strFilePath.erase();
				strFilePath = startDir + "\\" + fileInformation.cFileName;

				if(fileInformation.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
				{
					
					if(PathIsDirectoryEmpty(strFilePath.c_str()))
					{
						storedFiles.push_back(strFilePath);
						
					}

					int res = searchEmptyDirs(storedFiles, strFilePath);
					if(res)
						return res;
				}
			}
		}while(FindNextFileA(hFile, &fileInformation) == TRUE);

		FindClose(hFile);

		DWORD dwError = GetLastError();
		if(dwError != ERROR_NO_MORE_FILES)
			return dwError;
	}

	return 0;
}
Edit:
Und wie gehe ich Ordner die mit einem '.' beginnen durch? Also zB: .Bilder
01/29/2014 15:21 nerdsupreme#2
lass dich nicht so von deinen gefühlen leiten.
02/04/2014 00:21 Nightblizard#3
Du kannst die Rekusion verbessern, indem du ganz auf sie verzichtest!

Code:
#include <iostream>
#include <vector>
#include <algorithm>
#include <filesystem>

namespace sys = std::tr2::sys;

std::vector<sys::path> getEmptyDirectories(const sys::path& in)
{
	std::vector<sys::path> directories;

	if (!sys::exists(in))
		return directories;

	sys::directory_iterator begin(in);
	sys::directory_iterator end;

	std::for_each(begin, end, [&](sys::directory_entry directoryEntry)
	{
		auto path = directoryEntry.path();

		if (sys::is_directory(path) && sys::is_empty(path))
			directories.push_back(path);
	});

	return directories;
}

int main()
{
	auto directories = getEmptyDirectories(sys::current_path<sys::path>());

	std::cout << "Directories:\n";
	std::copy(directories.begin(), directories.end(), std::ostream_iterator<std::string>(std::cout, "\n"));

	std::cin.get();
	return 0;
}
Benötigt derzeit noch Visual Studio 2013, aber das wird noch dieses Jahr Standard, wodurch das dann später auch mit dem GCC laufen wird.

Das hier hat folgende Vorteile:
-Keine Rekursion
-Plattformübergreifend
-Lesbarer & Kürzer (dadurch wartbarer)
-Robuster durch strong exception safety
-Mehr Buzzwörter die mir gerade nicht einfallen