最近遇到一个需求,即需要将文件夹A里的图片一部分移动到文件夹B,另一部分移动到文件夹C。
而需要移动到B和C的图片的名称分别保存在两个txt文本中,每个图片名称占一行。
txt文本如下:
因为图片的名称比较复杂,对着找比较麻烦,因此做一个小工具来自动化完成。只需三步:
1 加载txt文本
2 选择图片所在文件夹
3 选择目标文件夹
4 点击移动
这样就完成了一次移动。
效果如下:
思路很简单,就是读取txt中的文件名存到列表里,移动时使用QFile::copy()函数就可以了,如果想剪切过去
可以在复制后加载QFile::remove()函数。
主要代码:
#include "fileMove.h"
#include <QFileDialog>
#include <QMessageBox>
#include <QProgressDialog>
#include <QTimer>
#include <QEventLoop>
#include "windows.h"
#include "qwaiting.h"
QProgressDialog *progDlg = NULL;
int currentValue = 0;
fileMove::fileMove(QWidget *parent)
: QWidget(parent)
{
ui.setupUi(this);
this->setWindowTitle(QString::fromLocal8Bit("文件移动"));
}
void fileMove::selectText()
{
m_fileList.clear();
QString filePath = QFileDialog::getOpenFileName(this);
if (filePath.isEmpty())
{
QMessageBox::warning(this, QStringLiteral("提示"), QString::fromLocal8Bit("加载失败!"));
return;
}
QFile file(filePath);
if (file.open(QIODevice::ReadOnly | QIODevice::Text))
{
while (!file.atEnd())
{
QByteArray line = file.readLine();
QString str(line);
m_fileList.append(str);
QCoreApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
}
file.close();
}
int iSize = m_fileList.size();
QMessageBox::warning(this, QStringLiteral("提示"), QString::fromLocal8Bit("共加载%1个图片!").arg(iSize));
}
void fileMove::selectSrc()
{
m_Src = QFileDialog::getExistingDirectory(this, QStringLiteral("选择源目录"), "/");
//m_Src = QString::fromLocal8Bit(temp.toStdString().c_str());
}
void fileMove::selectDest()
{
m_Dest = QFileDialog::getExistingDirectory(this, QStringLiteral("选择目标目录"), "/");
//m_Dest = QString::fromLocal8Bit(temp.toStdString().c_str());
}
void fileMove::startMove()
{
if (m_Dest.isEmpty() || m_Src.isEmpty() || m_fileList.isEmpty())
{
QMessageBox::warning(this, QStringLiteral("提示"), QString::fromLocal8Bit("请先选择必要参数!"));
return;
}
QString srcFileName;
QString destFileName;
int iSucceed = 0;
/*动图显示*/
/*QWaiting *pQwait = new QWaiting(this);
pQwait->show();
for (int i = 0; i < m_fileList.size(); i++)
{
srcFileName = m_Src + "/" + m_fileList.at(i);
destFileName = m_Dest + "/" + m_fileList.at(i);
if (QFile::copy(srcFileName.simplified(), destFileName.simplified()))
{
iSucceed = iSucceed + 1;
}
QCoreApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
}
pQwait->close();*/
QApplication::setOverrideCursor(Qt::WaitCursor);//设置鼠标为等待状态
QProgressDialog progress;
progress.setWindowTitle(QString::fromLocal8Bit("提示"));
progress.setLabelText(QString::fromLocal8Bit("正在移动中..."));
progress.setCancelButtonText(QString::fromLocal8Bit("取消"));
progress.setRange(0, m_fileList.size());//设置范围
progress.setModal(true);//设置为模态对话框
progress.show();
for (int i = 0; i < m_fileList.size(); i++)
{
srcFileName = m_Src + "/" + m_fileList.at(i);
destFileName = m_Dest + "/" + m_fileList.at(i);
if (QFile::copy(srcFileName.simplified(), destFileName.simplified()))
{
progress.setValue(i);
iSucceed = iSucceed + 1;
}
//用户取消的话则中止
if (progress.wasCanceled())
{
break;
}
QCoreApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
//QCoreApplication::processEvents();
}
QApplication::restoreOverrideCursor();
progress.close();
QMessageBox::warning(this, QStringLiteral("提示"), QString::fromLocal8Bit("共移动%1个文件!").arg(iSucceed));
}
这里的进度条可以参考我的上一篇博客:
https://blog.csdn.net/qq_24282081/article/details/95782291
这里遇到一个问题,就是QFile::copy总是失败,GetLastError()返回值是123.
错误是:文件名、目录名或卷标语法不正确。
找了很久,发现原因是自己拼接的文件名称后面多了一个"\n"符,因此要用simplified()去掉它。
这就提醒我调试时要细心,看一下字符的每一个字节。
例子下载:
https://download.csdn.net/download/qq_24282081/11344372
最后附上一段同事用python写的文件移动脚本,注意路径为双反斜杠,且不支持中文
import os, shutil
srcDir = "I:\\trigger0701\\12cheTrigger"
dstDir = "I:\\trigger0701\\12che"
lst = os.listdir(srcDir)
for i in range(0, len(lst)):
fileName = lst[i]
filePath = os.path.join(srcDir, fileName)
if os.path.isdir(filePath):
subLst = os.listdir(filePath)
for j in range(0, len(subLst)):
subfileName = subLst[j]
subfilePath = os.path.join(srcDir, fileName, subfileName)
if os.path.isfile(subfilePath):
newFilePath = os.path.join(dstDir, subfileName)
if os.path.exists(newFilePath):
print(" ")
else:
shutil.move(subfilePath, newFilePath)