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?
risposta
#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;
}
}
@ namar0x0309 Ho applicato la tua modifica, che è corretta. – Gigi
lì, questa è la risposta portatile. –
L'unica cosa che non ha funzionato per me è la 'e', l'ho sostituita con '&&'. Il resto è eccellente. +1 –
Non si dice quale sistema operativo si è, ma ci sono diverse opzioni.
Come i commentatori hanno menzionato, boost::filesystem funzionerà se è possibile utilizzare boost.
Altre opzioni sono
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);
}
}
Le tue soluzioni troveranno il file nel modello "foo.txt.exe". Non lo considererei per avere un'estensione .txt. –
Su windows, dove stai impostando il valore di "gIgnoreHidden". È una bandiera? – hshantanu
sì - è un booleano globale nell'esempio. Ma in realtà puoi fare qualsiasi cosa qui - come passarlo come un altro argomento per elencare i file. –
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++;
}
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;
}
[ 'boost :: filesystem'] (http://www.boost.org/doc/libs/1_41_0/libs/filesystem/doc/index.htm) funziona bene con i file. – chris
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
Fantastico, grazie per il riferimento. Lo controllerò. – Jim