Политика конфиденциальностиКонтактыО сайтеОтзывыGitHubDonate
© EVILEG 2015-2018
Рекомендует хостинг
TIMEWEB
R
24 мая 2018 г. 7:37

Скачивание больших файлов

Добрый день.


Подскажите пожалуйста, какими средствами можно скачивать большие файлы из интернета с помощью QT, например: архивы, ресурсные *.rcc файлы и т.п.
Можно ли для этого использовать облачные хранилища (например Dropbox), или же для этого нужен свой сервер и т.п.
Рекомендуем хостинг TIMEWEB
Рекомендуем хостинг TIMEWEB
Стабильный хостинг, на котором располагается социальная сеть EVILEG. Для проектов на Django рекомендуем VDS хостинг.
7

Добрый день.


В принципе, размер файла будет влиять только на длительность скачивания. А средства для скачивания все будут одни и теже.
Я бы рекомендовал использовать QNetworkAccessManager. Он без проблем может скачивать всё, что необходимо.

Почитать можно в следующих статьях:
0
R

Пытаюсь скачать картинку *.png, используя пример из урока 035.

По следующей ссылке:
QUrl url("https://drive.google.com/uc?export=download&confirm=no_antivirus&id=18JxR-2y8qtskhRD0MhKToSue9euMYZUh");
Файл создаю тоже формата *.png:
QFile *file = new QFile("D:/123.png");
В дебаге получаю сообщение "Downloading is completed", но по итогу появляется файл размером 1кб.

Что я делаю не так?
0
R

Банально даже *.exe файл не могу скачать таким способом. Текст по примеру - да, качается. А вот какие-либо файлы - нет.

void Downloader::getData()
{
    QUrl url("http://download.qt.io/official_releases/online_installers/qt-unified-windows-x86-online.exe"); // URL, к которому будем получать данные
    QNetworkRequest request;    // Отправляемый запрос
    request.setUrl(url);        // Устанавлвиваем URL в запрос
    manager->get(request);      // Выполняем запрос
}

void Downloader::onResult(QNetworkReply *reply)
{
    // Если в процесе получения данных произошла ошибка
    if(reply->error()){
        // Сообщаем об этом и показываем информацию об ошибках
        qDebug() << "ERROR";
        qDebug() << reply->errorString();
    } else {
        // В противном случае создаём объект для работы с файлом
        QFile *file = new QFile("D:/123.exe");
        // Создаём файл или открываем его на перезапись ...
        if(file->open(QFile::WriteOnly)){
            QByteArray content= reply->readAll();
            file->write(content);  // ... и записываем всю информацию со страницы в файл
            file->close();                  // закрываем файл
        qDebug() << "Downloading is completed";
        emit onReady(); // Посылаем сигнал о завершении получения файла
        }
    }
}
0

Фу... Ну Вы и задачку подбросили...

Проблема оказалась в том, что те URL, которые вы показали в качестве примера имеют редиректы. Это не прямые ссылки. Например в случае с инсталлятором Qt - это редирект с кодом 302.
Я написал пробное приложение для скачивания (чуть позже статью выложу) и пытался с помощью него понять, что не так. Пока не заглянул в содержимое того, что скачивалось. Там прямым текстом было написано, что файл перемещён, а данный URL является редиректом.
Чтобы справиться с этой проблемой нужно просто разрешить запросам следовать по редиректам.

Попробуйте так сделать
void Downloader::getData()
{
    QUrl url("http://download.qt.io/official_releases/online_installers/qt-unified-windows-x86-online.exe"); // URL, к которому будем получать данные
    QNetworkRequest request;    // Отправляемый запрос
    request.setUrl(url);        // Устанавлвиваем URL в запрос
    request.setAttribute(QNetworkRequest::FollowRedirectsAttribute, true);
    manager->get(request);      // Выполняем запрос
}
0
R

Спасибо! Работает.


Но появились новые проблемы:
1) Данные висят в ОЗУ до закрытия программы. Если бы это был архив весом в 2гб+ - это было бы проблемой.
2) Данные скачиваются огромным пакетом. Пока искал решение первичной проблемы, набрел на обсуждение использования функции readyRead(), которая позволяет записывать данные кусками сразу, не загружая при этом весь файл в ОЗУ, но так и не понял как с ней обращаться. Переопределять этот метод или как... Не пойму.
3) Как можно прикрутить к этому ProgressBar, который показывал бы прогресс и скорость?
4) Если делать функцию "отмены закачки", получается нужно определять QNetworkReply reply и QFile file ещё в конструкторе, и работать с ними в отдельном методе ?
reply->abort();
reply->deleteLater();
file.close();
file.remove();
P.s. Где вообще следует использовать deleteLater()? В вашем примере его, например, нет.
0

На первые три вопрос ответы есть вот в этой новой статье по QNetworkAccessManager и созданию Downloadera .

Что касается последнего вопроса, то нужно вызывать deleteLater когда реквест отработал и reply уже не нужен. Но удалять его нужно именно через deleteLater.
0
R

Понял, большое спасибо.

1

Комментарии

Только авторизованные пользователи могут публиковать комментарии.
Пожалуйста, авторизуйтесь или зарегистрируйтесь
IT
25 марта 2019 г. 17:32
Ilya The Engineer

Qt - Тест 001. Сигналы и слоты

  • Результат:5баллов,
  • Очки рейтинга-10
G
25 марта 2019 г. 8:34
GAG

C++ - Тест 002. Константы

  • Результат:41баллов,
  • Очки рейтинга-8
G
25 марта 2019 г. 8:25
GAG

C++ - Тест 001. Первая программа и типы данных

  • Результат:66баллов,
  • Очки рейтинга-1
Последние комментарии
22 марта 2019 г. 12:32
Евгений Легоцкой

Ну может бибилотеки не те положили? У вас сборка для MinGW, а либы для MSVC.
ВН
22 марта 2019 г. 11:08
Волчонок Над-Пропастью

Из кьюта приложение не хочет запускаться, аварийно завершается, но каких-либо ошибок не выдаёт. Оно открывается, после нажатия "старт" зависает и завершается. Если не из кьюта запускать дебаг ...
21 марта 2019 г. 15:49
Евгений Легоцкой

серьезно? Эта ошибка 404 уже даже не относится к данному вопросу. В каких-то urls в вашем проекте. Вопросы, которые не относятся непосредственно к статье, задавайте, пожалуйста на...
АБ
21 марта 2019 г. 15:00
Артем Бел

а это где? сейчас ошибка в debag такая: Page not found (404)Request Method: GETRequest URL: http://amadowshop.site/accounts/profile/
21 марта 2019 г. 12:47
Евгений Легоцкой

не вижу здесь проблемы, поменяйте url для callback в приложения oauth в социальных сетях https://amadowshop.site/auth/verify/complete/facebook/
Сейчас обсуждают на форуме
U
25 марта 2019 г. 12:43
Unreal_man

Как сделать чтоб при клике на ячейку(ос андроид) ее сразу можно было редактировать?QGuiApplication::inputMethod()->show(); показывает клавиатуру, а вот что до этого прописать чтоб текст в ...
m
24 марта 2019 г. 10:36
monevich

Отвечу на свой же вопрос, может кому то это пригодится. Да, можно в функции main использовать такую конструкцию. При запуске программы из Qt передаю свой аргумент в параметрах командной строк...
22 марта 2019 г. 12:29
Дмитрий

Да, мьютекс добавил, но в том потоке, где сигнал вызывается.
ВН
22 марта 2019 г. 9:04
Волчонок Над-Пропастью

Да, на эту проблему! Зато у меня теперь новая, ругается на подключение QMediaPlayer, пишет, что не находит подобного файла или библиотеки. Пока не нашла как исправить, только вариант с переуст...
22 марта 2019 г. 8:58
Михаиллл

4) это , похоже, для создания видоизмененных страниц, для анимации. 3,5) добавить фвйл/qt/ui.qml
Присоединяйтесь к нам в социальных сетях

Для зарегистрированных пользователей на сайте присутствует минимальное количество рекламы