Как вы рекурсивно перебираете каждый файл / каталог в стандартном C ++?
c++
filesystems
робот
источник
источник
Ответы:
В стандартном C ++ технически нет возможности сделать это, поскольку в стандартном C ++ нет концепции каталогов. Если вы хотите немного расширить свою сеть, вы можете использовать Boost.FileSystem . Это было принято для включения в TR2, так что это дает вам наилучшие шансы сохранить вашу реализацию как можно ближе к стандарту.
Пример взят прямо с сайта:
источник
Начиная с C ++ 17,
<filesystem>
заголовок и диапазон-for
вы можете просто сделать это:Начиная с C ++ 17,
std::filesystem
является частью стандартной библиотеки и может быть найден в<filesystem>
заголовке (больше не «экспериментальный»).источник
using
, используйтеnamespace
вместо этого.При использовании Win32 API вы можете использовать функции FindFirstFile и FindNextFile .
http://msdn.microsoft.com/en-us/library/aa365200(VS.85).aspx
Для рекурсивного обхода каталогов вы должны проверить каждый WIN32_FIND_DATA.dwFileAttributes, чтобы проверить, установлен ли бит FILE_ATTRIBUTE_DIRECTORY . Если бит установлен, вы можете рекурсивно вызывать функцию с этим каталогом. В качестве альтернативы вы можете использовать стек для обеспечения того же эффекта рекурсивного вызова, но избегая переполнения стека для очень длинных деревьев путей.
источник
Вы можете сделать это еще проще с помощью нового диапазона C ++ 11
for
и Boost :источник
Быстрое решение - использование библиотеки C Dirent.h .
Фрагмент рабочего кода из Википедии:
источник
В дополнение к вышеупомянутой boost :: filesystem вы можете захотеть изучить wxWidgets :: wxDir и Qt :: QDir .
И wxWidgets, и Qt являются кроссплатформенными фреймворками C ++ с открытым исходным кодом.
wxDir
предоставляет гибкий способ рекурсивного обхода файлов с помощьюTraverse()
или более простойGetAllFiles()
функции. А также вы можете реализовать обход сGetFirst()
иGetNext()
функции (я предполагаю , что Traverse () и GetAllFiles () являются оболочками , которые в конечном итоге используют GetFirst () и GetNext () функции).QDir
обеспечивает доступ к структурам каталогов и их содержимому. Есть несколько способов перемещаться по каталогам с помощью QDir. Вы можете перебирать содержимое каталога (включая подкаталоги) с помощью QDirIterator, экземпляр которого был создан с помощью флага QDirIterator :: Subdirectories. Другой способ - использовать функцию QDir GetEntryList () и реализовать рекурсивный обход.Вот пример кода (взят из здесь # Пример 8-5) , который показывает , как перебрать все подкаталоги.
источник
Boost :: filesystem предоставляет recursive_directory_iterator, что довольно удобно для этой задачи:
источник
Вы можете использовать
ftw(3)
илиnftw(3)
обходить иерархию файловой системы на C или C ++ в системах POSIX .источник
nftw()
использования.Вы этого не сделаете. В стандарте C ++ нет понятия каталогов. Преобразование строки в дескриптор файла зависит от реализации. Содержимое этой строки и то, чему она сопоставляется, зависит от ОС. Имейте в виду, что C ++ можно использовать для написания этой ОС, поэтому он используется на уровне, на котором вопрос о том, как выполнять итерацию по каталогу, еще не определен (поскольку вы пишете код управления каталогом).
Посмотрите документацию по API вашей ОС, чтобы узнать, как это сделать. Если вам нужно быть портативным, вам понадобится набор #ifdef для различных ОС.
источник
Вам, вероятно, лучше всего подойдет либо boost, либо экспериментальная файловая система C ++ 14. ЕСЛИ вы анализируете внутренний каталог (т.е. используемый вашей программой для хранения данных после закрытия программы), тогда создайте индексный файл, который имеет индекс содержимого файла. Кстати, вам, вероятно, понадобится использовать boost в будущем, поэтому, если он у вас не установлен, установите его! Во-вторых, вы можете использовать условную компиляцию, например:
Код для каждого случая взят из https://stackoverflow.com/a/67336/7077165
источник
Вам нужно вызвать специфичные для ОС функции для обхода файловой системы, такие как
open()
иreaddir()
. Стандарт C не определяет никаких функций, связанных с файловой системой.источник
Мы живем в 2019 году. У нас есть стандартная библиотека файловой системы в формате
C++
.Filesystem library
Предоставляет средства для выполнения операций на файловых систем и их компонентов, таких как пути, для обычных файлов и каталогов.По этой ссылке есть важное примечание, если вы рассматриваете проблемы переносимости. Он говорит:
Библиотека файловой системы была первоначально разработана как
boost.filesystem
техническая спецификация ISO / IEC TS 18822: 2015, опубликована как техническая спецификация ISO / IEC TS 18822: 2015 и, наконец, объединена с ISO C ++ начиная с C ++ 17. Реализация boost в настоящее время доступна на большем количестве компиляторов и платформ, чем библиотека C ++ 17.@ adi-shavit ответил на этот вопрос, когда он был частью std :: experimental, и он обновил этот ответ в 2017 году. Я хочу подробнее рассказать о библиотеке и показать более подробный пример.
std :: filesystem :: recursive_directory_iterator - это
LegacyInputIterator
элемент, который выполняет итерацию по элементам directory_entry в каталоге и, рекурсивно, по записям всех подкаталогов. Порядок итерации не указан, за исключением того, что каждая запись каталога посещается только один раз.Если вы не хотите рекурсивно перебирать записи подкаталогов, следует использовать directory_iterator .
Оба итератора возвращают объект directory_entry .
directory_entry
имеет различные функции полезны членам , какis_regular_file
,is_directory
,is_socket
, иis_symlink
т.д.path()
Функция член возвращает объект станд :: файловой системы :: путь , и он может быть использован для полученияfile extension
,filename
,root name
.Рассмотрим пример ниже. Я использовал
Ubuntu
и скомпилировал его через терминал, используяg ++ example.cpp --std = c ++ 17 -lstdc ++ fs -Wall
источник
Вы этого не сделаете. Стандартный C ++ не раскрывает понятие каталога. В частности, он не дает возможности перечислить все файлы в каталоге.
Ужасным взломом было бы использование вызовов system () и анализ результатов. Наиболее разумным решением было бы использовать какую-то кроссплатформенную библиотеку, такую как Qt или даже POSIX .
источник
Вы можете использовать
std::filesystem::recursive_directory_iterator
. Но будьте осторожны, это включает в себя символические (программные) ссылки. Если вы хотите избежать их, вы можете использоватьis_symlink
. Пример использования:источник
Если вы работаете в Windows, вы можете использовать FindFirstFile вместе с FindNextFile API. Вы можете использовать FindFileData.dwFileAttributes, чтобы проверить, является ли данный путь файлом или каталогом. Если это каталог, вы можете рекурсивно повторить алгоритм.
Здесь я собрал код, в котором перечислены все файлы на машине Windows.
http://dreams-soft.com/projects/traverse-directory
источник
Обход дерева файлов
ftw
- это рекурсивный способ ограничить все дерево каталогов на пути. Более подробная информация здесь .ПРИМЕЧАНИЕ. Вы также можете использовать это,
fts
чтобы пропускать скрытые файлы, такие как.
или..
или.bashrc
вывод выглядит следующим образом:
Допустим, если вы хотите сопоставить имя файла (пример: поиск всех
*.jpg, *.jpeg, *.png
файлов) для определенных нужд, используйтеfnmatch
.источник