Просто то, чем я хочу поделиться и поблагодарить вас за материал для чтения. Поиграйте с функцией, чтобы немного ее понять. Вам может понравиться это. e обозначает расширение, p обозначает путь, а s обозначает разделитель пути.
Если путь пройден без конечного разделителя, разделитель будет добавлен к пути. Для расширения, если введена пустая строка, функция вернет любой файл, который не имеет расширения в своем имени. Если была введена одна звезда, будут возвращены все файлы в каталоге. Если длина e больше 0, но не является единичным *, то точка e будет добавлена к e, если e не содержала точку в нулевой позиции.
Для возвращаемого значения. Если возвращается карта нулевой длины, то ничего не найдено, но каталог открыт. Если из возвращаемого значения доступен индекс 999, но размер карты равен только 1, это означало, что возникла проблема с открытием пути к каталогу.
Обратите внимание, что для повышения эффективности эту функцию можно разделить на 3 меньшие функции. Кроме того, вы можете создать функцию вызывающей стороны, которая будет определять, какую функцию она будет вызывать, основываясь на вводе. Почему это более эффективно? Сказано, что если вы собираетесь захватить все, что является файлом, то при использовании этого метода подфункция, созданная для захвата всех файлов, будет просто захватывать все файлы и не должна оценивать какие-либо другие ненужные условия при каждом обнаружении файла.
Это также относится к случаям, когда вы получаете файлы, которые не имеют расширения. Специальная встроенная функция для этой цели будет оценивать погоду только в том случае, если найденный объект является файлом, а затем, будет ли имя файла содержать точку.
Экономия может быть незначительной, если вы только читаете каталоги с небольшим количеством файлов. Но если вы читаете большое количество каталогов или если в каталоге содержится пара сотен тысяч файлов, это может быть огромной экономией.
#include <stdio.h>
#include <sys/stat.h>
#include <iostream>
#include <dirent.h>
#include <map>
std::map<int, std::string> getFile(std::string p, std::string e = "", unsigned char s = '/'){
if ( p.size() > 0 ){
if (p.back() != s) p += s;
}
if ( e.size() > 0 ){
if ( e.at(0) != '.' && !(e.size() == 1 && e.at(0) == '*') ) e = "." + e;
}
DIR *dir;
struct dirent *ent;
struct stat sb;
std::map<int, std::string> r = {{999, "FAILED"}};
std::string temp;
int f = 0;
bool fd;
if ( (dir = opendir(p.c_str())) != NULL ){
r.erase (999);
while ((ent = readdir (dir)) != NULL){
temp = ent->d_name;
fd = temp.find(".") != std::string::npos? true : false;
temp = p + temp;
if (stat(temp.c_str(), &sb) == 0 && S_ISREG(sb.st_mode)){
if ( e.size() == 1 && e.at(0) == '*' ){
r[f] = temp;
f++;
} else {
if (e.size() == 0){
if ( fd == false ){
r[f] = temp;
f++;
}
continue;
}
if (e.size() > temp.size()) continue;
if ( temp.substr(temp.size() - e.size()) == e ){
r[f] = temp;
f++;
}
}
}
}
closedir(dir);
return r;
} else {
return r;
}
}
void printMap(auto &m){
for (const auto &p : m) {
std::cout << "m[" << p.first << "] = " << p.second << std::endl;
}
}
int main(){
std::map<int, std::string> k = getFile("./", "");
printMap(k);
return 0;
}