Вопрос по filesystems, file-management, c++ – Как получить список файлов с определенным расширением в заданной папке?

40

Я хочу получить имена всех файлов с определенным расширением в заданной папке (и рекурсивно, ее подпапки). То есть имя файла (и расширение), а не полный путь к файлу. Это невероятно просто в таких языках, как Python, но я не знаком с конструкциями для этого в C ++. Как это можно сделать?

Написание C ++ после Python должно быть похоже на написание на ассемблере после C ++ :) Что касается стандарта C ++, то это удивительно трудоемкая задача. Я второй предложение использованияboost::filesystem. dasblinkenlight
boost::filesystem хорошо с файлами. chris

Ваш Ответ

5   ответов
48
#define BOOST_FILESYSTEM_VERSION 3
#define BOOST_FILESYSTEM_NO_DEPRECATED 
#include <boost/filesystem.hpp>

namespace fs = ::boost::filesystem;

// return the filenames of all files that have the specified extension
// in the specified directory and all subdirectories
void get_all(const fs::path& root, const string& ext, vector<fs::path>& ret)
{
    if(!fs::exists(root) || !fs::is_directory(root)) return;

    fs::recursive_directory_iterator it(root);
    fs::recursive_directory_iterator endit;

    while(it != endit)
    {
        if(fs::is_regular_file(*it) && it->path().extension() == ext) ret.push_back(it->path().filename());
        ++it;

    }

}
кодusing namespace std; (следует добавить, что)
@Jav_Rock Вы, скорее всего, используете VS и должны включить & lt; iso646.h & gt; получить не символьные логические операторы.
Единственное, что не работает для меня, это "и", я заменил его на "и". В остальном отлично. +1
Примечание: для расширения не забудьте добавить точку ... например ".jpg" является правильным, а не "jpg".
вот это портативный ответ.
16

На окнах вы делаете что-то вроде этого:

void listFiles( const char* path )
{
   struct _finddata_t dirFile;
   long hFile;

   if (( hFile = _findfirst( path, &dirFile )) != -1 )
   {
      do
      {
         if ( !strcmp( dirFile.name, "."   )) continue;
         if ( !strcmp( dirFile.name, ".."  )) continue;
         if ( gIgnoreHidden )
         {
            if ( dirFile.attrib & _A_HIDDEN ) continue;
            if ( dirFile.name[0] == '.' ) continue;
         }

         // dirFile.name is the name of the file. Do whatever string comparison 
         // you want here. Something like:
         if ( strstr( dirFile.name, ".txt" ))
            printf( "found a .txt file: %s", dirFile.name );

      } while ( _findnext( hFile, &dirFile ) == 0 );
      _findclose( hFile );
   }
}

На Posix, как Linux или OsX:

void listFiles( const char* path )
{
   DIR* dirFile = opendir( path );
   if ( dirFile ) 
   {
      struct dirent* hFile;
      errno = 0;
      while (( hFile = readdir( dirFile )) != NULL ) 
      {
         if ( !strcmp( hFile->d_name, "."  )) continue;
         if ( !strcmp( hFile->d_name, ".." )) continue;

         // in linux hidden files all start with '.'
         if ( gIgnoreHidden && ( hFile->d_name[0] == '.' )) continue;

         // dirFile.name is the name of the file. Do whatever string comparison 
         // you want here. Something like:
         if ( strstr( hFile->d_name, ".txt" ))
            printf( "found an .txt file: %s", hFile->d_name );
      } 
      closedir( dirFile );
   }
}
На сборках x64 от Windows 8 (?) И далее, я считаю, что hFile должен быть intptr_t, а не long. Использование long приведет к ошибкам при вызове _findnext.
да - это глобальное логическое значение в примере. Но на самом деле вы можете сделать все что угодно - например, передать это в качестве еще одного аргумента для listFiles.
Ваши решения найдут файл в шаблоне & quot; foo.txt.exe & quot ;. Я бы не подумал, что это расширение .txt.
В окнах, где вы устанавливаете значение «gIgnoreHidden». Это флаг?
2

Вы не говорите, в какой ОС вы работаете, но есть несколько вариантов.

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

Другие варианты

3

Получить список файлов и обработать каждый файл, просмотреть их и сохранить в другой папке

void getFilesList(str,ing filePath,string extension, vector<string> & returnFileName)
{
    WIN32_FIND_DATA fileInfo;
    HANDLE hFind;   
    string  fullPath = filePath + extension;
    hFind = FindFirstFile(fullPath.c_str(), &fileInfo);
    if (hFind != INVALID_HANDLE_VALUE){
        returnFileName.push_back(filePath+fileInfo.cFileName);
        while (FindNextFile(hFind, &fileInfo) != 0){
            returnFileName.push_back(filePath+fileInfo.cFileName);
        }
    }
}

ИСПОЛЬЗОВАНИЕ: вы можете использовать, как это загрузить все файлы из папки и перебрать один за другим

String optfileName ="";        
String inputFolderPath =""; 
String extension = "*.jpg*";
getFilesList(inputFolderPath,extension,filesPaths);
vector<string>::const_iterator it = filesPaths.begin();
while( it != filesPaths.end())
{
    frame = imread(*it);//read file names
        //doyourwork here ( frame );
    sprintf(buf, "%s/Out/%d.jpg", optfileName.c_str(),it->c_str());
    imwrite(buf,frame);   
    it++;
}
8

код C ++ 17

#include <fstream>
#include <iostream>
#include <experimental/filesystem>
namespace fs = std::experimental::filesystem;

int main()
{
    std::string path("/your/dir/");
    std::string ext(".sample");
    for(auto& p: fs::recursive_directory_iterator(path)
    {
        if(p.path().extension() == ext())
            std::cout << p << '\n';
    }
    return 0;
}

Похожие вопросы