1. 最近出于需要写了一个linux和windows 下通用的遍历文件夹下指定文件的函数,函数功能基本该有的都有了,下面是代码:
#ifndef OSTOOLKIT_HPP
#define OSTOOLKIT_HPP
#include <vector>
#include <algorithm>
#include <sstream>
#ifdef __linux__
#include <unistd.h>
#include <dirent.h>
#endif
#ifdef WIN32
#include <direct.h>
#include <io.h>
#endif
using std::string;
using std::vector;
namespace ToolKit{
//function: get files list under a directory
//get all files with pointed exts (if necessary) under a directory
//const string& dir: the iuput directory
//const string& extension: extension of files, "*" means everything, more than one ext could be connected by '|'
//bool isRecursive = false: whether to handle the subdir
//bool withpath = false: whether to return the whole path of files, if set true, withpath will automatically be set true
//return valaue--vector<string>: a vector contained all the found files
std::vector<std::string> GetDirFiles(const std::string& dir, const std::string& extension, bool isRecursive, bool withpath);
std::vector<std::string>& Split(const std::string &s, char delim, std::vector<std::string> &elems);
std::vector<std::string> Split(const std::string &s, char delim);
std::vector<std::string>& Split(const std::string &s, char delim, std::vector<std::string> &elems) {
std::istringstream ss(s);
std::string item;
while (std::getline(ss, item, delim)) {
// ignore spaces
if (item.find_first_not_of(' ') == std::string::npos)
continue;
elems.push_back(item);
}
return elems;
}
std::vector<std::string> Split(const std::string &s, char delim) {
std::vector<std::string> elems;
return Split(s, delim, elems);
}
std::vector<std::string> GetDirFiles(const std::string& dir, const std::string& exts = "*", bool isRecursive = false, bool withpath = false){
if (isRecursive)
withpath = true;
// preprocess the path
std::string tmp_dir = dir;
if (dir.back() != '/' && dir.back() != '\\')
tmp_dir = dir + "/";
// to support the multi-exts
std::vector<std::string> vec_ext;
Split(exts, '|', vec_ext);
std::vector<std::string> filenames;
#ifdef __linux__
DIR *pDIR;
struct dirent *entry;
if (pDIR = opendir(tmp_dir.c_str())){
while (entry = readdir(pDIR)){
std::string filename = entry->d_name;
if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0)
continue;
if (entry->d_type == 4){ // handle the subdir
if (isRecursive){
vector<string> vFiles4subfolder = GetDirFiles(tmp_dir + entry->d_name, exts, isRecursive, withpath);
filenames.insert(filenames.end(), vFiles4subfolder.begin(), vFiles4subfolder.end());
}
else
continue;
}
bool isMatch = false;
for (size_t i = 0; i < vec_ext.size(); i++){
if (vec_ext[i] == "*"){
isMatch = true;
break;
}
else if (filename.substr(filename.find_last_of(".") + 1) == vec_ext[i])
isMatch = true;
}
if (isMatch){
if (withpath)
filenames.push_back(tmp_dir + filename);
else
filenames.push_back(filename);
}
}
closedir(pDIR);
}
#endif
#ifdef WIN32
std::string tmp;
long long Handle; // handle should be 64 to ensure funtion work properly in 64-bit system
struct __finddata64_t file;
if ((Handle = _findfirst64(tmp.assign(tmp_dir).append("*").c_str(), &file)) != -1l){ // long __cdecl _findfirst(const char *, struct _finddata_t *)
do{ // int __cdecl _findnext(long, struct _finddata_t *);if find the file name successfully, return 0, else return -1
if (file.attrib & _A_NORMAL) {/* do nothing */ }
else if (file.attrib & _A_RDONLY) {/* do nothing */ }
else if (file.attrib & _A_HIDDEN) {/* do nothing */ }
else if (file.attrib & _A_SYSTEM) {/* do nothing */ }
else if (file.attrib & _A_SUBDIR) {
if (isRecursive && strcmp(file.name, ".") != 0 && strcmp(file.name, "..") != 0){
std::vector<std::string> vFilesubfolder = GetDirFiles(tmp.assign(tmp_dir).append(file.name), exts, isRecursive, withpath);
filenames.insert(filenames.end(), vFilesubfolder.begin(), vFilesubfolder.end());
}
else
continue;
}
else{
bool isMatch = false;
std::string tmp_filename = file.name;
for (size_t i = 0; i < vec_ext.size(); i++){
if (vec_ext[i] == "*"){
isMatch = true;
break;
}
else if (tmp_filename.substr(tmp_filename.find_last_of(".") + 1) == vec_ext[i]){
isMatch = true;
break;
}
}
if (isMatch){
if (withpath)
filenames.push_back(tmp_dir + tmp_filename);
else
filenames.push_back(tmp_filename);
}
}
} while (_findnext64(Handle, &file) == 0);
}
_findclose(Handle);
#endif
std::sort(filenames.begin(), filenames.end());
return filenames;
}
} // namespace ToolKit
#endif // OSTOOLKIT_HPP