Загрузка больших файлов на C++ - Вопросы и ответы, обсуждения - Ваши вопросы по C/C++ только в данном разделе
04.04.2013, 22:47
#1
Пехотинец
Регистрация: 11.01.2012
Сообщений: 84
Популярность: 3472
Сказал(а) спасибо: 97
Поблагодарили 182 раз(а) в 97 сообщениях
Загрузка больших файлов на C++
Всем привет,
Моя программа загружает нужный компонент с сайта, раньше он весил 17 кб / 17 408 байт и можно было просто поставить максимальный размер буффера в функции (65 536) и эта проблема как бы отходила, но после упаковки файл стал весить 1,35 МБ, стало быть это 1 421 312 байт, мне нужен правильный код, чтобы выделить память, скачать, сохранить в файл и освободить память.
Вот мой предыдущий код:
Код:
int Get( char* szUrl, char* szFile )
{
BYTE cBuffer[ INTERNET_GET_MAX ];
HINTERNET hInternet = InternetOpenA( INTERNET_LOGIN, INTERNET_OPEN_TYPE_PRECONFIG, 0, 0, 0 );
HINTERNET hFile = InternetOpenUrlA( hInternet, szUrl, 0, 0, INTERNET_FLAG_RELOAD, 0 );
DWORD dwReadSize = INTERNET_GET_MAX - 1;
int uResult = InternetReadFile( hFile, cBuffer, dwReadSize, &dwReadSize );
cBuffer[ dwReadSize ] = '\0';
InternetCloseHandle( hInternet );
InternetCloseHandle( hFile );
if ( uResult )
{
DeleteFileA( szFile );
HANDLE hOutputFile = CreateFileA( szFile, GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_ALWAYS, 0, 0 );
uResult = WriteFile( hOutputFile, cBuffer, dwReadSize, &dwReadSize, 0 );
CloseHandle( hOutputFile );
return ( uResult ) ? ( uResult ) : ( 0 - GetLastError( ) );
}
return ( 0 - GetLastError( ) );
}
INTERNET_GET_MAX - 65 536, как уже писала ранее.
Возможно удастся как-то по частям загрузить.
П.с. курила malloc, все равно не очень понятно.
Заранее спасибо вам.
Последний раз редактировалось Annedroid; 04.04.2013 в 22:53 .
05.04.2013, 01:17
#2
Пехотинец
Регистрация: 07.07.2012
Сообщений: 60
Популярность: 171
Сказал(а) спасибо: 3
Поблагодарили 11 раз(а) в 10 сообщениях
Re: Загрузка больших файлов на C++
Код:
int Get( char* szUrl, char* szFile )
{
BYTE *cBuffer = NULL;
DWORD dwReadSize = 0;
HINTERNET hInternet = InternetOpenA( INTERNET_LOGIN, INTERNET_OPEN_TYPE_PRECONFIG, 0, 0, 0 );
HINTERNET hFile = InternetOpenUrlA( hInternet, szUrl, 0, 0, INTERNET_FLAG_RELOAD, 0 );
if (!InternetQueryDataAvailable(hFile, &dwReadSize, 0, 0))
return -1;
cBuffer = new BYTE[dwReadSize];
if (!cBuffer)
return -2;
int uResult = InternetReadFile( hFile, cBuffer, dwReadSize, &dwReadSize );
cBuffer[ dwReadSize ] = '\0';
InternetCloseHandle( hInternet );
InternetCloseHandle( hFile );
if ( uResult )
{
DeleteFileA( szFile );
HANDLE hOutputFile = CreateFileA( szFile, GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_ALWAYS, 0, 0 );
uResult = WriteFile( hOutputFile, cBuffer, dwReadSize, &dwReadSize, 0 );
CloseHandle( hOutputFile );
return ( uResult ) ? ( uResult ) : ( 0 - GetLastError( ) );
}
delete [] cBuffer;
return ( 0 - GetLastError( ) );
}
Как то так.
- Запрос размера файла через InternetQueryDataAvailable
- Динамически выделяем память в соответствии с размером доступного файла
И, если выходишь из функции прямо из "if", то не забудь сначала освободить память (delete [] cBuffer).
За основу взята инфа из RSDN - [
Ссылки могут видеть только зарегистрированные пользователи. ]
Последний раз редактировалось twice; 05.04.2013 в 01:23 .
Пользователь сказал cпасибо:
05.04.2013, 15:49
#3
Пехотинец
Регистрация: 11.01.2012
Сообщений: 84
Популярность: 3472
Сказал(а) спасибо: 97
Поблагодарили 182 раз(а) в 97 сообщениях
Re: Загрузка больших файлов на C++
Цитата:
Спасибо вам, ваш код работает!
П.с. если кому-то нужен мой класс AInternet:
[
Ссылки могут видеть только зарегистрированные пользователи. ]
Последний раз редактировалось Annedroid; 05.04.2013 в 16:22 .
Пользователь сказал cпасибо:
05.04.2013, 16:40
#4
Пехотинец
Регистрация: 07.07.2012
Сообщений: 60
Популярность: 171
Сказал(а) спасибо: 3
Поблагодарили 11 раз(а) в 10 сообщениях
Re: Загрузка больших файлов на C++
Цитата:
И, если выходите из функции прямо из "if", то не забудьте сначала освободить память (delete [] cBuffer).
Код:
if ( uResult )
{
DeleteFileA( szFile );
HANDLE hOutputFile = CreateFileA( szFile, GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_ALWAYS, 0, 0 );
uResult = WriteFile( hOutputFile, cBuffer, dwReadSize, &dwReadSize, 0 );
CloseHandle( hOutputFile );
return ( uResult ) ? ( uResult ) : ( 0 - GetLastError( ) );
}
Перед return забыто "delete [] cBuffer", что приведет к утечки памяти при правильном исходе работы функции (функция Get).
Также рекомендую обернуть все содержимое заголовочника в
Код:
#ifndef AINTERNET_H
#define AINTERNET_H
тут тело заголовочника
#endif
Это поможет избежать ошибок компиляции/линковки, если данный заголовочник будет подключен в нескольких модулях.
Последний раз редактировалось twice; 05.04.2013 в 16:48 .
Пользователь сказал cпасибо:
05.04.2013, 17:58
#5
Пехотинец
Регистрация: 11.01.2012
Сообщений: 84
Популярность: 3472
Сказал(а) спасибо: 97
Поблагодарили 182 раз(а) в 97 сообщениях
Re: Загрузка больших файлов на C++
Спасибо... Учила, а не все помню...
11.05.2013, 15:03
#6
Пехотинец
Регистрация: 07.07.2012
Сообщений: 60
Популярность: 171
Сказал(а) спасибо: 3
Поблагодарили 11 раз(а) в 10 сообщениях
Re: Загрузка больших файлов на C++
Annedroid , взяв твой класс за основу, немного доработал его.
[Ссылки могут видеть только зарегистрированные пользователи. ]
Может кому-нибудь пригодится.
Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения
HTML код Выкл.
Заявление об ответственности / Список мошенников
Часовой пояс GMT +4, время: 20:23 .