2012-06-21 15 views
36

Desidero ottenere i nomi file di tutti i file che hanno un'estensione specifica in una determinata cartella (e in modo ricorsivo, le relative sottocartelle). Cioè, il nome del file (e l'estensione), non il percorso completo del file. Questo è incredibilmente semplice in linguaggi come Python, ma non ho familiarità con i costrutti per questo in C++. Come può essere fatto?Come ottenere l'elenco dei file con un'estensione specifica in una determinata cartella?

+7

[ 'boost :: filesystem'] (http://www.boost.org/doc/libs/1_41_0/libs/filesystem/doc/index.htm) funziona bene con i file. – chris

+0

Scrivere C++ dopo che Python deve sentirsi come scrivere in un linguaggio assembly dopo C++ :) Per quanto riguarda lo standard C++, questo è un compito sorprendentemente ricco di codice. Seguo il suggerimento di usare 'boost :: filesystem'. – dasblinkenlight

+0

Fantastico, grazie per il riferimento. Lo controllerò. – Jim

risposta

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; 

    } 

} 
+0

@ namar0x0309 Ho applicato la tua modifica, che è corretta. – Gigi

+2

lì, questa è la risposta portatile. –

+2

L'unica cosa che non ha funzionato per me è la 'e', ​​l'ho sostituita con '&&'. Il resto è eccellente. +1 –

16

Su Windows si fa qualcosa di simile:

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

Su Posix, come Linux o 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); 
    } 
} 
+0

Le tue soluzioni troveranno il file nel modello "foo.txt.exe". Non lo considererei per avere un'estensione .txt. –

+0

Su windows, dove stai impostando il valore di "gIgnoreHidden". È una bandiera? – hshantanu

+0

sì - è un booleano globale nell'esempio. Ma in realtà puoi fare qualsiasi cosa qui - come passarlo come un altro argomento per elencare i file. –

3

lista Get di file e di processo ogni file e loop-through li e riporli in un'altra cartella

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

USO: è possibile utilizzare come questo carico tutti i file dalla cartella e ciclo attraverso uno per uno

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

un codice 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; 
} 
Problemi correlati