394 lines
13 KiB
C++
394 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 <qfiledialog.h>
|
|
#include <filesystem>
|
|
|
|
class fileManager
|
|
{
|
|
public:
|
|
static QString openFolderDialog()
|
|
{
|
|
QString folderPath = QFileDialog::getExistingDirectory(
|
|
nullptr,
|
|
"Select Folder",
|
|
QDir::homePath(), // 默认路径,可以根据需要更改
|
|
QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks);
|
|
|
|
if (!folderPath.isEmpty()) {
|
|
// 用户选择了文件夹
|
|
qDebug() << "Selected Folder: " << folderPath;
|
|
}
|
|
else {
|
|
// 用户取消了选择
|
|
qDebug() << "Folder selection canceled.";
|
|
}
|
|
|
|
return folderPath;
|
|
}
|
|
/// <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(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> files=getAllDirs(folderPath);
|
|
for (auto file : files)
|
|
{
|
|
QFileInfo fileInfo(QString::fromStdString(file));
|
|
QDateTime fileTime = fileInfo.created();
|
|
QDateTime nowTime = QDateTime::currentDateTime();
|
|
if (fileTime.daysTo(nowTime) > day)
|
|
{
|
|
QDir dir(QString::fromStdString(file));
|
|
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(QString path,clearMode mode,QTimer *timer)
|
|
{
|
|
detPath = path;
|
|
detMode = mode;
|
|
connect(timer, &QTimer::timeout, this, [=]() {this->run(); });
|
|
}
|
|
~autoDelete()
|
|
{
|
|
|
|
}
|
|
void run() override
|
|
{
|
|
exacute();
|
|
}
|
|
void exacute()
|
|
{
|
|
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:
|
|
QString detPath;
|
|
clearMode detMode;
|
|
int daySet = 15;//天
|
|
int sizeSet = 30;//GB
|
|
int threadInterval = 0;//ms
|
|
};
|
|
|
|
#pragma once
|