main.cpp 范例文件

download/main.cpp
/**************************************************************************** ** ** Copyright (C) 2016 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the examples of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:BSD$ ** Commercial License Usage ** Licensees holding valid commercial Qt licenses may use this file in ** accordance with the commercial license agreement provided with the ** Software or, alternatively, in accordance with the terms contained in ** a written agreement between you and The Qt Company. For licensing terms ** and conditions see https://www.qt.io/terms-conditions. For further ** information use the contact form at https://www.qt.io/contact-us. ** ** BSD License Usage ** Alternatively, you may use this file under the terms of the BSD license ** as follows: ** ** "Redistribution and use in source and binary forms, with or without ** modification, are permitted provided that the following conditions are ** met: ** * Redistributions of source code must retain the above copyright ** notice, this list of conditions and the following disclaimer. ** * Redistributions in binary form must reproduce the above copyright ** notice, this list of conditions and the following disclaimer in ** the documentation and/or other materials provided with the ** distribution. ** * Neither the name of The Qt Company Ltd nor the names of its ** contributors may be used to endorse or promote products derived ** from this software without specific prior written permission. ** ** ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." ** ** $QT_END_LICENSE$ ** ****************************************************************************/
#include <QCoreApplication> #include <QFile> #include <QFileInfo> #include <QList> #include <QNetworkAccessManager> #include <QNetworkRequest> #include <QNetworkReply> #include <QSslError> #include <QStringList> #include <QTimer> #include <QUrl> #include <stdio.h> class QSslError; QT_USE_NAMESPACE class DownloadManager: public QObject { Q_OBJECT QNetworkAccessManager manager; QList<QNetworkReply *> currentDownloads; public: DownloadManager(); void doDownload(const QUrl &url); QString saveFileName(const QUrl &url); bool saveToDisk(const QString &filename, QIODevice *data); public slots: void execute(); void downloadFinished(QNetworkReply *reply); void sslErrors(const QList<QSslError> &errors); }; DownloadManager::DownloadManager() { connect(&manager, SIGNAL(finished(QNetworkReply*)), SLOT(downloadFinished(QNetworkReply*))); } void DownloadManager::doDownload(const QUrl &url) { QNetworkRequest request(url); QNetworkReply *reply = manager.get(request); #ifndef QT_NO_SSL connect(reply, SIGNAL(sslErrors(QList<QSslError>)), SLOT(sslErrors(QList<QSslError>))); #endif currentDownloads.append(reply); } QString DownloadManager::saveFileName(const QUrl &url) { QString path = url.path(); QString basename = QFileInfo(path).fileName(); if (basename.isEmpty()) basename = "download"; if (QFile::exists(basename)) { // already exists, don't overwrite int i = 0; basename += '.'; while (QFile::exists(basename + QString::number(i))) ++i; basename += QString::number(i); } return basename; } bool DownloadManager::saveToDisk(const QString &filename, QIODevice *data) { QFile file(filename); if (!file.open(QIODevice::WriteOnly)) { fprintf(stderr, "Could not open %s for writing: %s\n", qPrintable(filename), qPrintable(file.errorString())); return false; } file.write(data->readAll()); file.close(); return true; } void DownloadManager::execute() { QStringList args = QCoreApplication::instance()->arguments(); args.takeFirst(); // skip the first argument, which is the program's name if (args.isEmpty()) { printf("Qt Download example - downloads all URLs in parallel\n" "Usage: download url1 [url2... urlN]\n" "\n" "Downloads the URLs passed in the command-line to the local directory\n" "If the target file already exists, a .0, .1, .2, etc. is appended to\n" "differentiate.\n"); QCoreApplication::instance()->quit(); return; } foreach (QString arg, args) { QUrl url = QUrl::fromEncoded(arg.toLocal8Bit()); doDownload(url); } } void DownloadManager::sslErrors(const QList<QSslError> &sslErrors) { #ifndef QT_NO_SSL foreach (const QSslError &error, sslErrors) fprintf(stderr, "SSL error: %s\n", qPrintable(error.errorString())); #else Q_UNUSED(sslErrors); #endif } void DownloadManager::downloadFinished(QNetworkReply *reply) { QUrl url = reply->url(); if (reply->error()) { fprintf(stderr, "Download of %s failed: %s\n", url.toEncoded().constData(), qPrintable(reply->errorString())); } else { QString filename = saveFileName(url); if (saveToDisk(filename, reply)) printf("Download of %s succeeded (saved to %s)\n", url.toEncoded().constData(), qPrintable(filename)); } currentDownloads.removeAll(reply); reply->deleteLater(); if (currentDownloads.isEmpty()) // all downloads finished QCoreApplication::instance()->quit(); } int main(int argc, char **argv) { QCoreApplication app(argc, argv); DownloadManager manager; QTimer::singleShot(0, &manager, SLOT(execute())); app.exec(); } #include "main.moc"