(Owed by: 春夜喜雨 http://blog.csdn.net/chunyexiyu)
磁盘空间约占用越大了,一些程序我们只想留源码,其它都不想留了(像obj,dll,link等),这样空间从几十G,立刻降到几十上几百M,降了几个数量级–空间就立刻省出来了!
所以手动写了一个程序来处理:
需求:
- 实现递归查找文件,匹配后缀符合的留下
- 提供一个简单易用的界面
实现上-技术:
- 借助QT的Qdir,Qfile方法遍历文件夹
- 借助QT布局界面
- 借助QfileDialog选择文件夹
- 借助线程来避免界面卡死
- 借助QMovie和一个动态图片实现等待中效果
Part1:递归查找的实现 :
void CopyDirsEx(QString sSrcPath, QString sDestPath)
{
// 目录打开并检查
QDir dirSrc(sSrcPath);
if (!dirSrc.exists())
return;
// 设置过滤类型与文件排序方式
dirSrc.setFilter(QDir::Dirs|QDir::Files);
dirSrc.setSorting(QDir::DirsLast);
//获取文件信息列表
QFileInfoList fileInfoList = dirSrc.entryInfoList();
// 不为空,才创建列表
if (!fileInfoList.empty())
{
QDir().mkdir(sDestPath);
}
// 遍历处理
for (size_t i=0; i<fileInfoList.size(); i++)
{
QFileInfo fileInfo = fileInfoList.at(i);
// 处理特殊文件
if(fileInfo.fileName() == "." | fileInfo.fileName() == "..")
{
continue;
}
bool bIsDir = fileInfo.isDir();
if (bIsDir)
{
CopyDirsEx(sSrcPath + "\\" + fileInfo.fileName(), sDestPath + "\\" + fileInfo.fileName());
}
else
{
if (fileInfo.suffix() == "h"
|| fileInfo.suffix() == "cpp"
|| fileInfo.suffix() == "vcxproj"
|| fileInfo.suffix() == "sln"
|| fileInfo.suffix() == "bat"
|| fileInfo.suffix() == "filters"
|| fileInfo.suffix() == "proj"
|| fileInfo.suffix() == "ui"
|| fileInfo.suffix() == "qrc"
|| fileInfo.suffix() == "res")
{
bool bRt = QFile::copy(sSrcPath + "\\" + fileInfo.fileName(), sDestPath + "\\" + fileInfo.fileName());
if (!bRt)
{
QString sDebugInfo = QString("Copy %1 to %2 rt=%3")
.arg(sSrcPath + "\\" + fileInfo.fileName())
.arg(sDestPath + "\\" + fileInfo.fileName())
.arg(bRt);
qDebug(sDebugInfo.toLocal8Bit());
}
}
}
}
}
Part2: 执行线程等待的实现
class MyThreadWaitTask : public QObject
{
Q_OBJECT
public:
MyThreadWaitTask(){}
signals:
void finished();
public:
// 主线程调用:等待finished消息
void waitTaskFinish()
{
connect(this, SIGNAL(finished()), &m_loop, SLOT(quit()));
m_loop.exec();
}
// 子线程调用:发送finished消息
void onFinishProc()
{
emit finished();
}
private:
QEventLoop m_loop;
};
class MyCopyThread : public QThread
{
public:
MyCopyThread(QObject * pParent, MyThreadWaitTask* pTask, QString srcPath, QString destPath)
: QThread(pParent)
, m_pTask(pTask)
, m_sSrcPath(srcPath)
, m_sDestPath(destPath)
{
// 任务移入到线程中
pTask->moveToThread(this);
};
~MyCopyThread(){};
virtual void run();
private:
MyThreadWaitTask* m_pTask;
QString m_sSrcPath;
QString m_sDestPath;
};
Part3等待WaitDlg实现
WaitDlg::WaitDlg(QWidget *parent)
: QWidget(parent)
{
ui.setupUi(this);
m_pMovie = new QMovie(this);
m_pMovie->setFileName("Process.gif");
ui.m_labelShow->setMovie(m_pMovie);
m_pMovie->setScaledSize(QSize(100, 100));
m_pMovie->start();
}
Part4界面相关调用的实现
void GetCppSrcFiles::onProcessFiles()
{
QString sSrcPath = ui.editSrcPath->text();
QString sDestPath = ui.editDestPath->text();
if (sSrcPath.isEmpty() || sDestPath.isEmpty())
{
return;
}
// 目录打开并检查
QDir dirSrc(sSrcPath);
if (!dirSrc.exists())
return;
// 目录打开并检查
QDir dirDest(sDestPath);
if (!dirDest.exists())
{
if (!dirDest.mkdir(sDestPath))
{
qDebug("open dest foder error!");
return;
}
}
// 显示处理等待WaitDlg & 禁用按钮
WaitDlg dlg(this);
dlg.show();
ui.btnProc->setEnabled(false);
// 启动线程处理并等待处理完成
MyThreadWaitTask task;
MyCopyThread* pThread = new MyCopyThread(this, &task, sSrcPath, sDestPath);
task.waitTaskFinish();
pThread->start();
// 处理完成隐藏WaitDlg并启用按钮
dlg.hide();
ui.btnProc->setEnabled(true);
// 弹出提示处理完成
QMessageBox::information(this, "Info", "Pcoess finished!", QMessageBox::Ok);
}
void GetCppSrcFiles::onSelectSrc()
{
QString sFileName = QFileDialog::getExistingDirectory(this, tr(“Open Directory”));
if (!sFileName.isEmpty())
{
ui.editSrcPath->setText(sFileName);
}
}
void GetCppSrcFiles::onSelectDest()
{
QString sFileName = QFileDialog::getExistingDirectory(this, tr(“Open Directory”));
if (!sFileName.isEmpty())
{
ui.editDestPath->setText(sFileName);
}
}
(Owed by: 春夜喜雨 http://blog.csdn.net/chunyexiyu)