How to get list of files with a specific extension

2020-01-25 06:22发布

问题:

I want to get the file names of all files that have a specific extension in a given folder (and recursively, its subfolders). That is, the file name (and extension), not the full file path. This is incredibly simple in languages like Python, but I'm not familiar with the constructs for this in C++. How can it be done?

回答1:

#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;

    }

}


回答2:

On windows you do something like this:

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 );
   }
}

On Posix, like Linux or 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 );
   }
}


回答3:

a C++17 code

#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;
}


回答4:

Get list of files and process each file and loop through them and store back in different folder

void getFilesList(string 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);
        }
    }
}

USE: you can use like this load all the files from folder and loop through one by one

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++;
}


回答5:

You don't say what OS you are on, but there are several options.

As commenters have mentioned, boost::filesystem will work if you can use boost.

Other options are

  • CFileFind Class with MFC
  • FindFirstFile/FindNextFile with WIN32
  • opendir/readdir with POSIX.