Russian Qt Forum
Ноябрь 24, 2024, 21:47 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1] 2 3   Вниз
  Печать  
Автор Тема: QNetworkReply::readyRead()  (Прочитано 14581 раз)
Алёна_4_12_1989
Гость
« : Март 19, 2013, 13:15 »

Здравствуйте. У меня проблема. Я скачиваю большой файл на компьютер. Использую для этого сигнал QNetworkReply::finished(). Но при этом постоянно съедается оперативная память, так как насколько я поняла, она используется в этом классе. Как я могу сохранять файл по частям, используя readyRead() сигнал? Я не совсем это понимаю. Открыть файл, запустить QNetworkReply::get и ждать readyRead слот ? Но что делать в нем? Как сохранять и освобождать оперативку? Спасибо.
Записан
mutineer
Гость
« Ответ #1 : Март 19, 2013, 13:19 »

Цитировать
QNetworkReply is a sequential-access QIODevice, which means that once data is read from the object, it no longer kept by the device.

То бишь после прочтения из reply данных они больше не будут занимать память внутри reply
Записан
Алёна_4_12_1989
Гость
« Ответ #2 : Март 19, 2013, 13:29 »

т.е. при выходе из слота readyRead() память должна очищатся? или надо как-то считать эти данные? Я просто записываю их в файл, но в итоге программа делает crash из-за отсутствия памяти.
Записан
Bepec
Гость
« Ответ #3 : Март 19, 2013, 13:32 »

Кооод... нужен кооод... Покажи коооддд...
Записан
mutineer
Гость
« Ответ #4 : Март 19, 2013, 13:33 »

Не при выходе из слота, а при прочтении данных
Записан
Алёна_4_12_1989
Гость
« Ответ #5 : Март 19, 2013, 14:13 »

А как их прочесть?
Записан
Alex Custov
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2063


Просмотр профиля
« Ответ #6 : Март 19, 2013, 14:32 »

reply->readAll()
Записан
Алёна_4_12_1989
Гость
« Ответ #7 : Март 19, 2013, 14:35 »

я использую reply->readAll() функцию класса QNetworkReply. Это правильно? Но при этом всё равно не работает.

А код вот:

reply = network_manager->get(QNetworkRequest(url));
connect(reply, SIGNAL(readyRead()), this, SLOT(ready_read_slot()));

void ready_read_slot()
{
     reply->readAll(); // эти данные записываю в файл
}

Записан
mutineer
Гость
« Ответ #8 : Март 19, 2013, 14:38 »

"не работает" это очень распространенная проблема, да. Только универсального решения не придумали. Что и как не работает?
Записан
Алёна_4_12_1989
Гость
« Ответ #9 : Март 19, 2013, 14:41 »

ок, попробую конкретизировать. Спасибо.
Записан
Алёна_4_12_1989
Гость
« Ответ #10 : Март 19, 2013, 16:43 »

Программа падает на функции reply->readAll()
Первые два раза в слот readyRead программа заходит ( причем во втором случае количество bytesAvailible() больше, чем в первом - возможно это не новые данные, а все скачанные данные), а на третьем падает.
Записан
mutineer
Гость
« Ответ #11 : Март 19, 2013, 17:13 »

Покажи больше кода
Записан
Bepec
Гость
« Ответ #12 : Март 19, 2013, 17:16 »

Кооод... нужен кооод... Покажи коооддд...
Записан
Алёна_4_12_1989
Гость
« Ответ #13 : Март 19, 2013, 17:34 »

Вот мой код.

void DownloadManager::startDownload()
{
    if (network_manager)
    {
        m_reply = network_manager->get(QNetworkRequest(url));
        connect(m_reply, SIGNAL(downloadProgress(qint64,qint64)), this, SLOT(download_progress(qint64, qint64)));
        connect(m_reply, SIGNAL(readyRead()), this, SLOT(ready_read()));
        connect(m_reply, SIGNAL(finished()), this, SLOT(finish_download()));
        if (m_reply)
        {
            if (m_reply->error() == QNetworkReply::NoError)
            {
                file = new QFile();
                if (file)
                {
                    file->setFileName(fileName);
                    if (file->open(QIODevice::WriteOnly))
                    {
                        QByteArray my_array = m_reply->readAll();
                        int number = my_array.size();
                        m_reply->seek(0);
                        ::write(file->handle(), my_array.data(), number);
                        http.setHost(url.host(), url.port(80));
                        http.get(url.toEncoded(QUrl::RemoveScheme | QUrl::RemoveAuthority));
                    }
                }
            }
        }
    }
}

void DownloadManager::ready_read()
{
    if (m_reply)
    {
        qint64 value = m_reply->bytesAvailable();
        if (file)
        {
            QByteArray my_array = m_reply->readAll();
            int number = my_array.size();
            ::write(file->handle(), my_array.data(), number);
        }
    }
}

void DownloadManager::finish_download()
{
    if (file)
    {
        ::close(file->handle());
        m_reply->deleteLater();
        delete file;
    }
}
Записан
mutineer
Гость
« Ответ #14 : Март 19, 2013, 17:41 »

А для чего делается m_reply->seek(0); ? Он же бессмысленен для последовательных девайсов
Записан
Страниц: [1] 2 3   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.251 секунд. Запросов: 23.