Files
eUi/include/simpleTools/fileManager.h
T
2025-08-25 15:53:05 +08:00

387 lines
13 KiB
C++

#include<qstring.h>
#include <vector>
#include <string>
#include <qdir.h>
#include <io.h>
#include <qtimer.h>
#include <qthread.h>
#include <qdatetime.h>
#include <qstorageinfo.h>
#include <qdebug.h>
#include <iostream>
#include <filesystem>
class fileManager
{
public:
/// <summary>
/// 获取所有文件夹
/// </summary>
/// <param name="folderPath"></param>
/// <param name="folderNames"></param>
static std::vector<std::string> getAllDirs(const QString& folderPath)
{
std::vector<std::string> foldersVec;
QDir folderDir(folderPath);
if (!folderDir.exists()) {
return foldersVec;
}
QStringList folders = folderDir.entryList(QDir::Dirs | QDir::NoDotAndDotDot);
for (const QString& folder : folders) {
foldersVec.push_back(folderPath.toStdString()+"//" + folder.toStdString());
}
return foldersVec;
}
/// <summary>
/// 获取文件夹下格式的文件,以vector<string>返回
/// </summary>
/// <param name="path"></param>
/// <param name="files"></param>
/// <param name="format"></param>
static void getAllFiles(std::string path, std::vector<std::string>& files, std::string format, int targetDepth = INT_MAX, int depth = 0)
{
if (depth >= targetDepth)
return;
intptr_t hFile = 0;
struct _finddata_t fileinfo;
std::string p;
if ((hFile = _findfirst(p.assign(path).append("\\*" + format).c_str(), &fileinfo)) != -1)
{
do
{
if ((fileinfo.attrib & _A_SUBDIR))
{
if (strcmp(fileinfo.name, ".") != 0 && strcmp(fileinfo.name, "..") != 0)
{
files.push_back(p.assign(path).append("\\").append(fileinfo.name));
depth++;
getAllFiles(p.assign(path).append("\\").append(fileinfo.name), files, format, targetDepth ,depth);
}
}
else
{
files.push_back(p.assign(path).append("\\").append(fileinfo.name));
}
} while (_findnext(hFile, &fileinfo) == 0);
_findclose(hFile);
}
}
/// <summary>
/// 获取文件夹下的图片,以vector<string>返回
/// </summary>
/// <param name="path"></param>
/// <param name="files"></param>
/// <param name="format"></param>
static void getAllImages(std::string path, std::vector<std::string>& files, std::string format, int targetDepth = INT_MAX, int depth = 0)
{
if (depth >= targetDepth)
return;
intptr_t hFile = 0;
struct _finddata_t fileinfo;
std::string p;
if ((hFile = _findfirst(p.assign(path).append("\\*" + format).c_str(), &fileinfo)) != -1)
{
do
{
if ((fileinfo.attrib & _A_SUBDIR))
{
if (strcmp(fileinfo.name, ".") != 0 && strcmp(fileinfo.name, "..") != 0)
{
std::string filePath = p.assign(path).append("\\").append(fileinfo.name);
if (fileManager::isImageFile(filePath) == true)
files.push_back(filePath);
depth++;
getAllImages(filePath, files, format, targetDepth, depth);
}
}
else
{
std::string filePath = p.assign(path).append("\\").append(fileinfo.name);
if (fileManager::isImageFile(filePath) == true)
files.push_back(filePath);
}
} while (_findnext(hFile, &fileinfo) == 0);
_findclose(hFile);
}
}
/// <summary>
/// 检查磁盘剩余空间,以GB为单位返回
/// </summary>
/// <param name="folderPath">example"E://""E://111/222"支持文件夹或者磁盘路径</param>
/// <returns></returns>
static int getDriveFreeSpaceAsGb(const QString& folderPath) {
QStorageInfo storageInfo(folderPath);
if (storageInfo.isValid() && storageInfo.isReady()) {
return storageInfo.bytesAvailable() / 1073741824;
}
return -1; // Indicate failure to retrieve disk space
}
/// <summary>
/// 检查磁盘剩余空间,以Mb为单位返回
/// </summary>
/// <param name="folderPath">example"E://""E://111/222"支持文件夹或者磁盘路径</param>
/// <returns></returns>
static int getDriveFreeSpaceAsMb(const QString& folderPath) {
QStorageInfo storageInfo(folderPath);
if (storageInfo.isValid() && storageInfo.isReady()) {
return storageInfo.bytesAvailable() / 1048576;
}
return -1; // Indicate failure to retrieve disk space
}
/// <summary>
/// 返回最老创建时间文件夹名
/// </summary>
/// <param name="folderPath"></param>
/// <returns></returns>
static QString getOldestDir(const QString& folderPath)
{
std::string oldestDir;
QDateTime oldestTime;
std::vector<std::string> files= getAllDirs(folderPath);
for (auto file : files)
{
QFileInfo fileInfo(QString::fromStdString(folderPath.toStdString() + "//" + file));
QDateTime fileTime = fileInfo.created();
QString str = fileInfo.created().toString();
std::cout << "Current date and time: " << str.toStdString() << std::endl;
if (oldestTime.isNull() || fileTime < oldestTime)
{
oldestTime = fileTime;
oldestDir = file;
}
}
return QString::fromStdString(oldestDir);
}
/// <summary>
/// 删除最老创建时间文件夹
/// </summary>
/// <param name="folderPath"></param>
/// <returns></returns>
static bool deleteOldestDir(const QString& folderPath)
{
QString oldestDir =getOldestDir(folderPath);
if (oldestDir.isEmpty())
return false;
oldestDir= folderPath+ "//" + oldestDir;
QDir dir(oldestDir);
dir.removeRecursively();
return true;
}
/// <summary>
/// 删除最老子文件夹
/// </summary>
/// <param name="folderPath"></param>
/// <returns></returns>
static bool deleteOldestSonDir(const QString& folderPath)
{
QString oldestDir = getOldestDir(folderPath);
if (oldestDir.isEmpty())
return false;
oldestDir = folderPath + "//" + oldestDir;
deleteOldestDir(oldestDir);
if (getAllDirs(oldestDir).size() == 0)//删除后文件夹为空,删除父文件夹
{
QDir dir(oldestDir);
dir.removeRecursively();
}
return true;
}
/// <summary>
/// 删除几天前的所有文件夹
/// </summary>
/// <param name="folderPath"></param>
/// <param name="day"></param>
/// <returns></returns>
static bool deleteDirBeforeDays(const QString& folderPath, int day)
{
std::vector<std::string> dirs=getAllDirs(folderPath);
for (auto& dir : dirs)
{
QFileInfo fileInfo(QString::fromStdString(dir));
QDateTime fileTime = fileInfo.created();
QDateTime nowTime = QDateTime::currentDateTime();
std::string result = fileTime.toString("yyyy-MM-dd").toStdString();
int dayBefore = fileTime.daysTo(nowTime);
if (dayBefore > day)
{
QDir dir(QString::fromStdString(dir));
dir.removeRecursively();
}
}
return true;
}
//去除重复分割符
static QString normalizePathSeparators(const QString& path) {
QString normalizedPath = path;
// Replace backslashes with forward slashes
normalizedPath.replace('\\', '/');
// Remove consecutive forward slashes
QString doubleSlash = "//";
while (normalizedPath.contains(doubleSlash)) {
normalizedPath.replace(doubleSlash, "/");
}
return normalizedPath;
}
static bool isImageFile(const std::string& filename) {
const std::string imageExtensions[] = { ".jpg", ".jpeg", ".png", ".gif", ".bmp", ".tiff", ".webp" };
std::string lowerFilename = filename;
std::transform(lowerFilename.begin(), lowerFilename.end(), lowerFilename.begin(), [](unsigned char c) { return std::tolower(c); });
for (const std::string& ext : imageExtensions) {
if (lowerFilename.size() >= ext.size() &&
lowerFilename.compare(lowerFilename.size() - ext.size(), ext.size(), ext) == 0) {
return true;
}
}
return false;
}
static std::string getFileName(std::string path)
{
if (path.find("\\") != std::string::npos)
return path.substr(path.find_last_of("\\") + 1, path.find_last_of(".") - path.find_last_of("\\") - 1);
return path.substr(path.find_last_of("/") + 1, path.find_last_of(".") - path.find_last_of("/") - 1);
}
static QString getFileName(const QString& path) {
int lastSlashIndex = path.lastIndexOf('/');
if (lastSlashIndex == -1) {
lastSlashIndex = path.lastIndexOf('\\');
}
int lastDotIndex = path.lastIndexOf('.');
if (lastDotIndex == -1 || lastDotIndex < lastSlashIndex) {
return path.mid(lastSlashIndex + 1);
}
else {
return path.mid(lastSlashIndex + 1, lastDotIndex - lastSlashIndex - 1);
}
}
//统一地址分隔符
static QString normalizePathStr(const QString& address, QChar targetSeparator = '/') {
QString normalizedAddress = address;
for (int i = 0; i < normalizedAddress.size(); ++i) {
if (normalizedAddress[i] == '\\' || normalizedAddress[i] == '/') {
normalizedAddress[i] = targetSeparator;
}
}
return normalizedAddress;
}
//统一地址分隔符
static std::string normalizePathStr(const std::string& address, char targetSeparator = '/') {
std::string normalizedAddress = address;
for (char& ch : normalizedAddress) {
if (ch == '\\' || ch == '/') {
ch = targetSeparator;
}
}
return normalizedAddress;
}
static void createDirectoryIfNotExists(const std::string& path) {
// 检查路径是否存在
if (!std::filesystem::exists(path)) {
// 创建路径
std::filesystem::create_directories(path);
//std::cout << "已创建文件夹: " << path << std::endl;
}
else {/*
std::cout << "文件夹已存在: " << path << std::endl;*/
}
}
static bool setFileReadOnly(const std::string& filePath, bool readOnly);
};
/// <summary>
/// 自动删除文件夹,支持按日期删除,按磁盘剩余容量删除,或者两者都是,请在主线程声明qtimer
/// </summary>
class autoDelete : public QThread
{
Q_OBJECT
public:
enum clearMode
{
dayBefore,
sizeOver,
sizeOverOrDayBefore,
};
/// <summary>
/// 构造函数
/// </summary>
/// <param name="path">文件夹路径</param>
/// <param name="mode">删除几天前的,磁盘剩余容量小于多少,两者都是</param>
/// <param name="interval">检测间隔如果只检测日期建议设大一点,如果只检测磁盘容量建议设小一点,默认十分钟</param>
autoDelete(std::vector<std::string> pathVec,clearMode mode,int sec)
{
for (auto& path : pathVec)
detPathVec.push_back(QString::fromStdString(path));
detMode = mode;
threadInterval = sec;
this->start();
}
~autoDelete()
{
runFlag = false;
}
void run() override
{
while(runFlag)
{
exacute();
QThread::sleep(threadInterval);
}
}
void exacute()
{
for(auto & detPath : detPathVec)
{
switch (detMode)
{
case dayBefore://删除几天前的
fileManager::deleteDirBeforeDays(detPath, daySet);
break;
case sizeOver://磁盘剩余容量小于多少
if (fileManager::getDriveFreeSpaceAsGb(detPath) < sizeSet)
fileManager::deleteOldestSonDir(detPath);//删除最老的文件夹
break;
case sizeOverOrDayBefore://两者都是
if (fileManager::getDriveFreeSpaceAsGb(detPath) < sizeSet)//磁盘剩余容量小于多少
fileManager::deleteOldestDir(detPath);//删除最老的文件夹
fileManager::deleteDirBeforeDays(detPath, daySet);//同时删除几天前的
break;
default:
qDebug() << "none mode det";
break;
}
}
}
void setDay(int day)
{
daySet = day;
}
void setSize(int size)
{
sizeSet = size;
}
private:
std::vector<QString> detPathVec;
clearMode detMode;
int daySet = 30;//天
int sizeSet = 100;//GB
int threadInterval = 0;//sec
bool runFlag = true;
};
#pragma once