如何在给定的文件夹中获取具有特定扩展名的文件列表?

时间:2021-08-25 19:58:18

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?

我想获取在给定文件夹中具有特定扩展名的所有文件的文件名(递归地,是它的子文件夹)。即文件名(和扩展名),而不是完整的文件路径。这在Python之类的语言中非常简单,但是我不熟悉c++中的结构。怎么做呢?

5 个解决方案

#1


47  

#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


16  

On windows you do something like this:

在windows上,你可以这样做:

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:

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

#3


3  

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

#4


2  

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.

正如评论者所提到的,如果您可以使用boost,那么boost::文件系统将会工作。

Other options are

其他选项

#5


2  

a C++17 code

一个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;
}

#1


47  

#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


16  

On windows you do something like this:

在windows上,你可以这样做:

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:

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

#3


3  

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

#4


2  

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.

正如评论者所提到的,如果您可以使用boost,那么boost::文件系统将会工作。

Other options are

其他选项

#5


2  

a C++17 code

一个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;
}