筛选仅保留源文件的复制程序

时间:2021-04-09 09:17:15

(Owed by: 春夜喜雨 http://blog.csdn.net/chunyexiyu)
磁盘空间约占用越大了,一些程序我们只想留源码,其它都不想留了(像obj,dll,link等),这样空间从几十G,立刻降到几十上几百M,降了几个数量级–空间就立刻省出来了!

所以手动写了一个程序来处理:

需求:

  1. 实现递归查找文件,匹配后缀符合的留下
  2. 提供一个简单易用的界面

实现上-技术:

  1. 借助QT的Qdir,Qfile方法遍历文件夹
  2. 借助QT布局界面
  3. 借助QfileDialog选择文件夹
  4. 借助线程来避免界面卡死
  5. 借助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)