//
// Created by DangXS on 2022/4/27.
//
#ifndef CPLUSPLUS_PROJECT1_HELPER_H
#define CPLUSPLUS_PROJECT1_HELPER_H
#include <iostream>
#include <cstring>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include "dirent.h"
#include <ctime>
#include <string>
#include <vector>
#include <algorithm>
using namespace std;
#define MICRO_IN_SECOND 1000000
#define NANOS_IN_SECOND 1000000000
// 字符串分割到 vector
static vector<string> string_split(const string &str, const string &delim) {
vector<string> res;
if ("" == str) return res;
//先将要切割的字符串从string类型转换为char*类型
char *strs = new char[str.length() + 1]; //不要忘了
strcpy(strs, str.c_str());
char *d = new char[delim.length() + 1];
strcpy(d, delim.c_str());
char *p = strtok(strs, d);
while (p) {
string s = p; //分割得到的字符串转换为string类型
res.push_back(s); //存入结果数组
p = strtok(NULL, d);
}
return res;
}
// 获取文件后缀名
static string getExtension(const string &filename) {
return filename.substr(filename.find_last_of('.'));
}
// 判断是不是图片
static bool isImage(const string &filename) {
string ext = getExtension(filename);
vector<string> formats = {".jpg", ".jpeg", ".png", ".ppm", ".bmp", ".pgm", ".tif", ".tiff", ".webp"};
auto it = find(formats.begin(), formats.end(), ext);
return it != formats.end();
}
// 获取文件名,不包含目录
static string getFilename(const string &file_fullpath) {
return file_fullpath.substr(file_fullpath.find_last_of('/') + 1);
}
//获取文件名,不包含目录和后缀名
static string getFilenameNoExt(const string &filename) {
string _filename = getFilename(filename);
return _filename.substr(0, _filename.find_last_of('.'));
}
static string getParentPath(const string &file_fullpath) {
int idx = file_fullpath.find_last_of('/');
return file_fullpath.substr(0, idx);
}
// 获取文件绝对路径的父目录名
static string getParentDirname(string file_fullpath) {
vector<string> groups = string_split(file_fullpath, "/");
return groups[groups.size() - 2];
}
static bool pathIsExisted(const string &path) {
return access(path.c_str(), 0) == F_OK;
}
static bool isFolder(const string &path) {
if (!pathIsExisted(path)) {
printf_s("%s:%d not existed.\n", __FILE__, __LINE__, path.c_str());
return false;
}
struct stat buffer{};
return (stat(path.c_str(), &buffer)) == 0 && S_ISDIR(buffer.st_mode);
}
static bool isFile(const string &path) {
if (!pathIsExisted(path)) {
printf_s("%s:%d not existed.\n", __FILE__, __LINE__, path.c_str());
return false;
}
struct stat buffer{};
return (stat(path.c_str(), &buffer)) == 0 && S_ISREG(buffer.st_mode);
}
// 递归创建文件夹
static int mkDirsRecurive(string filename) {
filename += "/";
char *fileName = (char *) filename.c_str();
char *tag;
int a = 0;
for (tag = fileName; *tag; tag++, a++) {
if (*tag == '/') {
string new_path = filename.substr(0, a + 1);
if (access(new_path.c_str(), 0) == -1) //如果文件夹不存在
// mkdir(new_path.c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH); //则创建
mkdir(new_path.c_str());
}
}
return 0;
}
//读取某给定路径下所有文件夹与文件名称,并带完整路径
static void getAllFilesInDirs(const string &path, vector<string> &fileFullpath) {
DIR *pDir;
struct dirent *ptr;
if (!(pDir = opendir(path.c_str())))
return;
struct stat buffer{};
while ((ptr = readdir(pDir)) != 0) {
string new_path = path + "/" + ptr->d_name;
stat(new_path.c_str(), &buffer);
if (S_ISDIR(buffer.st_mode)) {
if (strcmp(ptr->d_name, ".") != 0 && strcmp(ptr->d_name, "..") != 0) {
getAllFilesInDirs(new_path, fileFullpath);
}
} else {
fileFullpath.push_back(path + "/" + ptr->d_name);
}
}
closedir(pDir);
}
//读取某给定路径下后缀名为format得文件名称,并带完整路径
static void getAllFilesByformat(const string &path, vector<string> &fileFullpath, const string &format) {
DIR *pDir;
struct dirent *ptr;
if (!(pDir = opendir(path.c_str())))
return;
while ((ptr = readdir(pDir)) != 0) {
string new_path = path + "/" + ptr->d_name;
if (isFolder(new_path)) {
if (strcmp(ptr->d_name, ".") != 0 && strcmp(ptr->d_name, "..") != 0) {
getAllFilesByformat(new_path, fileFullpath, format);
}
} else if (isFile(new_path) && getExtension(ptr->d_name) == format) {
string f = path + string("/") + string(ptr->d_name);
// std::cout << f << std::endl;
fileFullpath.push_back(f);
}
}
closedir(pDir);
}
// 文件重命名
static int file_rename(string oldname, string newname) {
return rename(oldname.c_str(), newname.c_str());
}
// 文件移动
static int file_move(const string &src_filename, const string &dst_path) {
string command = "mv ";
command += src_filename;
command += " ";
command += dst_path; //mv /home/file1 /root/file2
system((char *) command.c_str());
return 0;
}
// 文件拷贝
static int file_copy(string src_filename, string dst_filename) {
string command = "cp ";
command += src_filename.c_str();
command += " ";
command += dst_filename.c_str(); //cp /home/file1 /root/file2
// printf("%s\n", command.c_str());
system((char *) command.c_str());
return 0;
}
// 打乱vector
static vector<string> vector_shuffle(vector<string> v1) {
vector<string> v2;
// 复制
v2.assign(v1.begin(), v1.end());
//打乱
random_shuffle(v2.begin(), v2.end());
return v2;
}
///替换指定字符串
static string replace_all(string str, const string &old_value, const string &new_value) {
string str1;
while (true) {
string::size_type pos(0);
if ((pos = str.find(old_value)) != string::npos)
str1 = str.replace(pos, old_value.length(), new_value);
else break;
}
return str1;
}
static std::string GetTime() {
time_t timep;
time(&timep);
char tmp[64];
strftime(tmp, sizeof(tmp), "%Y-%m-%d %H:%M:%S", localtime(&timep));
return tmp;
}
// 获取当前毫秒数
// 用于测试程序耗时
// elapsed time = (t2-t1)
static double GetCurrentMiliSec() {
struct timespec res{};
double ret = 0;
clock_gettime(CLOCK_MONOTONIC, &res);
ret = (double) (res.tv_sec * NANOS_IN_SECOND + res.tv_nsec) / MICRO_IN_SECOND;
return ret;
}
static bool cmp(const pair<int, float> &a, const pair<int, float> &b) {
return a.second > b.second;
}
#endif //CPLUSPLUS_PROJECT1_HELPER_H