1 Star 0 Fork 0

咖啡不解困/fileDownload

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
mainwindow.cpp 7.90 KB
一键复制 编辑 原始数据 按行查看 历史
咖啡不解困 提交于 2019-10-31 16:12 . 修改编码问题
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDebug>
#include <QMessageBox>
#include <QFileDialog>
#include <QDesktopServices>
const int g_bSzieMax = 1024;
const int g_kSizeMax = 1024 * 1024;
const int g_mSizeMax = 1024 * 1024 * 1024;
const long long g_gSizeMax = 1024 * 1024 * 1024 * 1024;
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
setWindowTitle(u8"文件下载器");
setFixedSize(700, 300);
manager = new QNetworkAccessManager(this);
mtimer = new QTimer();
connect(mtimer, SIGNAL(timeout()), this, SLOT(showSpeed()));
// http://5b0988e595225.cdn.sohucs.com/images/20180516/3fea28f2c55c4959a87e2f84487eb08e.jpeg
// ui->urlLineEdit->setText("http://xz5.jb51.net:81/201604/books/cprimer5_jb51.rar");
// ui->downloadPath->setText("F:/C++/QT/project/xxxx");
}
MainWindow::~MainWindow()
{
delete ui;
}
// 网络响应结束
void MainWindow::on_finished()
{
QFileInfo fileInfo;
fileInfo.setFile(downloadedFile->fileName());
downloadedFile->close();
delete downloadedFile;
downloadedFile = Q_NULLPTR;
reply->deleteLater();
reply = Q_NULLPTR;
// 停止计时
mtimer->stop();
ui->downLoad->setEnabled(true);
//打开下载的文件
if (ui->checkBox->isChecked())
{
QDesktopServices::openUrl(QUrl::fromLocalFile(ui->downloadPath->text().trimmed()));
}
}
// 读取缓冲区下载的数据
void MainWindow::on_readyRead()
{
downloadedFile->write(reply->readAll());
}
/**
* @brief MainWindow::on_downloadProgress
* @param bytesRead 已下载大小
* @param totalBytes 文件大小
*/
void MainWindow::on_downloadProgress(qint64 bytesRead, qint64 totalBytes)
{
ui->progressBar->setMaximum(totalBytes);
ui->progressBar->setValue(bytesRead);
hadLoadSize = bytesRead;
QString size = formatSize(hadLoadSize);
ui->downloaded->setText(size);
}
// 浏览设置下载路径
void MainWindow::on_choosePath_clicked()
{
QString filePath = QFileDialog::getExistingDirectory(this, QString::fromLocal8Bit("选择文件路径"), ".");
ui->downloadPath->setText(filePath);
}
void MainWindow::on_downLoad_clicked()
{
QString url = ui->urlLineEdit->text().trimmed();
qDebug() << url;
downLoadUrl = url;
if (url.isEmpty())
{
QMessageBox::information(this, u8"错误",
u8"请指定需要下载的URL", NULL);
return;
}
QUrl tmpUrl = QUrl::fromUserInput(url);
if (!tmpUrl.isValid())
{
QMessageBox::information(this, u8"错误",
u8"无效URL: " + url + u8"\n错误信息: " + tmpUrl.errorString(), NULL);
return;
}
showFileSize();
QString dirPath = ui->downloadPath->text().trimmed();
if (dirPath.isEmpty())
{
QMessageBox::information(this, u8"错误",
u8"请设置下载目录", NULL);
return;
}
QString newFileName = ui->fileName->text().trimmed();
QString fullFileName;
if (newFileName.isEmpty())
{
fullFileName = dirPath + "/" + tmpUrl.fileName();
}
else {
fullFileName = dirPath + "/" + newFileName;
}
if (QFile::exists(fullFileName))
{
QFile::remove(fullFileName);
}
downloadedFile = new QFile(fullFileName);
if (!downloadedFile->open(QIODevice::WriteOnly))
{
QMessageBox::information(this, u8"错误",
u8"临时文件打开错误", NULL);
return;
}
ui->downLoad->setEnabled(false);
// 500ms
mtimer->start(100);
startTime = QTime::currentTime();
reply = manager->get(QNetworkRequest(tmpUrl));
// 下载完响应finished信号
connect(reply, SIGNAL(finished()), this, SLOT(on_finished()));
// 缓冲区有新的下载数据时,响应readyRead信号
connect(reply, SIGNAL(readyRead()), this, SLOT(on_readyRead()));
// 下载进度控制
connect(reply, SIGNAL(downloadProgress(qint64, qint64)),
this, SLOT(on_downloadProgress(qint64, qint64)));
}
/**
* @brief MainWindow::getFileTotalSize 发送请求,获取头部信息
* @param url
* @return
*/
qint64 MainWindow::getFileTotalSize(QString url)
{
qint64 size = -1;
// 请求的次数,最多3次尝试
int tryTimes = 3;
do
{
QNetworkAccessManager manager;
// 事件循环,等待请求文件头信息结束;
QEventLoop loop;
// 超时,结束事件循环;
QTimer timer;
QNetworkReply *reply = manager.head(QNetworkRequest(url));
if (!reply)
{
continue;
}
connect(reply, SIGNAL(finished()), &loop, SLOT(quit()));
connect(&timer,SIGNAL(timeout()), &loop, SLOT(quit()));
// 超过2s结束事件循环,重新请求
timer.start(2000);
loop.exec();
if (reply->error() != QNetworkReply::NoError)
{
// 请求发生错误
qDebug() << reply->errorString();
continue;
}
else if (!timer.isActive())
{
// 请求超时,未获取到文件信息
qDebug() << "Request Timeout";
continue;
}
timer.stop();
QVariant var = reply->header(QNetworkRequest::ContentLengthHeader);
size = var.toLongLong();
reply->deleteLater();
break;
}while (tryTimes--);
return size;
}
/**
* @brief MainWindow::doubleToQString double转字符串并保留3位小数
* @param dbNum
* @return
*/
QString MainWindow::doubleToQString(const double &dbNum)
{
char *chCode;
chCode = new(std::nothrow)char[20];
// .3 是控制输出精度的,两位小数
sprintf(chCode, "%.3lf", dbNum);
QString strCode(chCode);
delete []chCode;
return strCode;
}
/**
* @brief MainWindow::formatSize 根据size大小转换显示格式
* @param size
* @return
*/
QString MainWindow::formatSize(qint64 size)
{
QString sizeStr;
if (size <= g_bSzieMax)
{
sizeStr = doubleToQString(size) + " B";
}
else if ((size > g_bSzieMax) && (size <= g_kSizeMax))
{
sizeStr = doubleToQString(double(size)/g_bSzieMax) + " KB";
}
else if ((size > g_kSizeMax) && (size <= g_mSizeMax))
{
sizeStr = doubleToQString(double(size)/g_kSizeMax) + " MB";
}
else if ((size > g_mSizeMax) && (size <= g_gSizeMax))
{
sizeStr = doubleToQString(double(size)/g_mSizeMax) + " GB";
}
return sizeStr;
}
//显示文件大小
void MainWindow::showFileSize()
{
qint64 size = getFileTotalSize(downLoadUrl);
QString sizeStr = formatSize(size);
ui->fileSize->setText(sizeStr);
}
void MainWindow::on_urlLineEdit_textChanged(const QString &arg1)
{
QUrl url = arg1;
QFileInfo info(url.path());
QString fileName(info.fileName());
ui->fileName->setText(fileName);
}
//显示速度
void MainWindow::showSpeed()
{
stopTime = QTime::currentTime();
// 已下载大小/(时间差(ms)/1000) --> byte/s
double speed = double(hadLoadSize) / startTime.msecsTo(stopTime) * 1000;
QString speedStr;
if (speed <= g_bSzieMax)
{
speedStr = doubleToQString(speed) + " B/s";
}
else if ((speed > g_bSzieMax) && (speed <= g_kSizeMax))
{
speedStr = doubleToQString(speed/g_bSzieMax) + " KB/s";
}
else if ((speed > g_kSizeMax) && (speed <= g_mSizeMax))
{
speedStr = doubleToQString(speed/g_kSizeMax) + " MB/s";
}
else if ((speed > g_mSizeMax) && (speed <= g_gSizeMax))
{
speedStr = doubleToQString(speed/g_mSizeMax) + " GB/s";
}
ui->speed->setText(speedStr);
}
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
C++
1
https://gitee.com/KaFeiBuJieKun/fileDownload.git
[email protected]:KaFeiBuJieKun/fileDownload.git
KaFeiBuJieKun
fileDownload
fileDownload
master

搜索帮助