Как пройтись по дереву каталогов шаг за шагом?

Я нашел много примеров прохождения по дереву каталогов, но мне нужно что-то немного другое. Мне нужен класс с некоторым методом, который при каждом вызове возвращает один файл из каталога и постепенно проходит по дереву каталогов. Как я могу сделать это, пожалуйста? Я использую функции FindFirstFile, FindNextFile и FindClose, я новичок в C ++. У меня есть что-то вроде этого …

Например, у меня есть это простое дерево каталогов

Parent(folder)\
file1.txt
file2.txt
Child(folder)\
file3.txt
file4.txt

и мне нужен класс с методом, например, getNextFile (), этот первый вызов возвращает file1.txt; второй вызов возвращает file2.txt, третий вызов возвращает Child (папку), четвертый вызов возвращает file3.txt и так далее …

Изменить на дубликат флага: мне нужно пройтись по дереву без do / while, while или for … Мне нужен какой-то итератор, который можно сохранить для последующего использования и продолжить с последнего файла, когда я прерываю просмотр, но в идеале только с использованием звонков winapi

WIN32_FIND_DATA fdFile;
HANDLE hFind = NULL;
if((hFind = FindFirstFile(sPath, &fdFile)) == INVALID_HANDLE_VALUE)
{
return false;
}
do
{
//do some job with fdFile
}
while(FindNextFile(hFind, &fdFile));

2

Решение

Используйте правильные инструменты. Повышение доступно так же хорошо, как и везде, и имеет методы, которые вы хотите.

От http://rosettacode.org/wiki/Walk_a_directory/Recursively#C.2B.2B:

#include "boost/filesystem.hpp"#include "boost/regex.hpp"#include <iostream>

using namespace boost::filesystem;

int main()
{
path current_dir("."); //
boost::regex pattern("a.*"); // list all files starting with a
for (recursive_directory_iterator iter(current_dir), end;
iter != end;
++iter)
{
std::string name = iter->path().filename().string();
if (regex_match(name, pattern))
std::cout << iter->path() << "\n";
}
}

удалите весь бизнес регулярных выражений, если вам все равно, соответствует ли ваш файл определенному шаблону.

РЕДАКТИРОВАТЬ:

Не могли бы вы объяснить, почему было бы плохо использовать напрямую вызовы API?

  1. это уродливо и трудно читать, еще труднее понять,
  2. это совсем не портативно, и что самое важное,
  3. Есть миллион угловых случаев, о которых вы должны позаботиться, возможно, при использовании сырых win api. Boost был написан людьми, которые делали это несколько сотен раз и прошли серьезную проверку кода, поэтому выбирайте путь сохранения и не изобретайте колесо заново.

По сути, винапи около двух десятилетий; там было много улучшения юзабилити в остальном мире. Если у вас нет действительно веской причины, я постараюсь абстрагировать как можно больше с помощью общих библиотек, таких как Boost.

Я думаю, что это не решает мою проблему, я отредактировал оригинальный пост, чтобы сделать его более понятным.

в основном нужно пройти по дереву без do / while, while или for … мне нужен какой-то итератор, который можно сохранить для дальнейшего использования

Это именно то, что делает мой ответ: дать вам итератор в цикле for. Я не понимаю, что не соответствует спецификации вашего редактора об этом.

Кроме того, было бы лучше использовать только WinAPI, потому что он должен работать на разных компьютерах с Windows, и установка boost может быть проблемой.

Вам не нужно устанавливать boost на любом из этих компьютеров. Boost :: filesystem может быть связан статически; Кроме того, способ старой школы Windows это делает просто boost_filesystem*.dll а также boost_system*.dll вместе с вашим двоичным Однако, если ваша цель — один исполняемый файл, содержащий все необходимые функции, вы все равно будете использовать статическое связывание, так что это абсолютно не проблема.

3

Другие решения

Вот родной C ++ способ сделать это на платформе Windows (с использованием инфраструктуры MFC):

void ListFiles(const CString& sPath)
{
CFileFind finder;

CString sWildcard(sPath);
sWildcard += _T("\\*.*");

BOOL bWorking = finder.FindFile(sWildcard);

while (bWorking)
{
bWorking = finder.FindNextFile();

if (finder.IsDots())
continue;

if (finder.IsDirectory())
{
CString sFilePath = finder.GetFilePath();
// TODO: do stuff here
ListFiles(sFilePath);
}
}

finder.Close();
}

Вы можете изменить подстановочную строку для целевых файлов, например *.текст и т.д. Вы также можете передать его в качестве параметра этой функции, чтобы сделать его более универсальным.

3

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector