c++ 下载文件并解压 在界面上进度条
时间: 2023-08-11 07:09:49 浏览: 158
下载文件,带进度条
实现这个功能需要使用一些 C++ 库和工具。此处提供一种实现方法,使用 libcurl 库下载文件,使用 zlib 库解压文件,使用 Qt 库创建界面和进度条。
首先,需要安装 libcurl 和 zlib 库。在 Ubuntu 系统上,可以使用以下命令进行安装:
```
sudo apt-get install libcurl4-openssl-dev zlib1g-dev
```
接下来,创建一个 C++ 项目,并在项目中添加以下文件:
1. `download.h`:包含下载文件的函数声明。
2. `download.cpp`:包含下载文件的函数定义。
3. `unzip.h`:包含解压文件的函数声明。
4. `unzip.cpp`:包含解压文件的函数定义。
5. `mainwindow.h`:包含界面和进度条的声明。
6. `mainwindow.cpp`:包含界面和进度条的定义。
`download.h` 文件内容如下:
```cpp
#ifndef DOWNLOAD_H
#define DOWNLOAD_H
#include <string>
class Downloader {
public:
Downloader();
~Downloader();
void download(const std::string& url, const std::string& output_path);
private:
void* curl_;
};
#endif // DOWNLOAD_H
```
`download.cpp` 文件内容如下:
```cpp
#include "download.h"
#include <curl/curl.h>
#include <fstream>
Downloader::Downloader() {
curl_global_init(CURL_GLOBAL_ALL);
curl_ = curl_easy_init();
}
Downloader::~Downloader() {
curl_easy_cleanup(curl_);
curl_global_cleanup();
}
static int write_callback(char* data, size_t size, size_t nmemb, void* userp) {
std::ofstream* file = reinterpret_cast<std::ofstream*>(userp);
file->write(data, size * nmemb);
return size * nmemb;
}
void Downloader::download(const std::string& url, const std::string& output_path) {
CURLcode res;
std::ofstream file(output_path, std::ios::binary);
curl_easy_setopt(curl_, CURLOPT_URL, url.c_str());
curl_easy_setopt(curl_, CURLOPT_WRITEFUNCTION, write_callback);
curl_easy_setopt(curl_, CURLOPT_WRITEDATA, &file);
res = curl_easy_perform(curl_);
file.close();
if (res != CURLE_OK) {
throw std::runtime_error("Failed to download file.");
}
}
```
`unzip.h` 文件内容如下:
```cpp
#ifndef UNZIP_H
#define UNZIP_H
#include <string>
class Unzipper {
public:
void unzip(const std::string& input_path, const std::string& output_path);
};
#endif // UNZIP_H
```
`unzip.cpp` 文件内容如下:
```cpp
#include "unzip.h"
#include <zlib.h>
#include <fstream>
#include <iostream>
void Unzipper::unzip(const std::string& input_path, const std::string& output_path) {
gzFile in_file = gzopen(input_path.c_str(), "rb");
std::ofstream out_file(output_path, std::ios::binary);
char buffer[4096];
int bytes_read;
while ((bytes_read = gzread(in_file, buffer, sizeof(buffer))) > 0) {
out_file.write(buffer, bytes_read);
}
gzclose(in_file);
out_file.close();
}
```
`mainwindow.h` 文件内容如下:
```cpp
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE
class Downloader;
class Unzipper;
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
private slots:
void on_downloadButton_clicked();
private:
Ui::MainWindow *ui;
Downloader* downloader_;
Unzipper* unzipper_;
};
#endif // MAINWINDOW_H
```
`mainwindow.cpp` 文件内容如下:
```cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "download.h"
#include "unzip.h"
#include <QMessageBox>
#include <QFileDialog>
#include <QProgressDialog>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
, downloader_(new Downloader)
, unzipper_(new Unzipper)
{
ui->setupUi(this);
}
MainWindow::~MainWindow()
{
delete ui;
delete downloader_;
delete unzipper_;
}
void MainWindow::on_downloadButton_clicked()
{
QString url = ui->urlLineEdit->text();
QString output_path = QFileDialog::getSaveFileName(this, "Save file", ".", "Zip files (*.zip)");
if (output_path.isEmpty()) {
return;
}
try {
downloader_->download(url.toStdString(), output_path.toStdString());
QProgressDialog progress("Extracting...", "Cancel", 0, 100, this);
progress.setWindowModality(Qt::WindowModal);
progress.show();
std::string input_path = output_path.toStdString();
std::string output_dir = input_path.substr(0, input_path.size() - 4);
unzipper_->unzip(input_path, output_dir);
QMessageBox::information(this, "Success", "File downloaded and extracted successfully.");
} catch (std::exception& e) {
QMessageBox::warning(this, "Error", e.what());
}
}
```
在 Qt Creator 中打开项目,编译并运行程序,即可看到界面和进度条。当用户点击“下载”按钮时,程序会下载指定 URL 的文件,并显示解压进度,最终将解压后的内容保存在和原始文件相同的目录下。
阅读全文