Поиск
Вход
Последние темы
Перепечатка материалов (в любом виде) с данного сайта без письменного разрешения администратора запрещена.
Copyright ©2010-2011 Mine.ChudoForum.Ru - Все права защищены
Программа для качки
Страница 1 из 1
Программа для качки
Любому человеку, знакомому с интернетом, известны такие программы-качалки, как
GetRight, Reget и Flashget. Их расплодилось великое множество, все они занимают первые места в
рейтингах и продаются за немалые деньги. Так что
давай сегодня напишем свой Reget, и ты сможешь демонстрировать всем знакомым девушкам свою
физиономию в about программы .
Реквизит
Он нам понадобится. Прошли те времена, когда все делалось в два диалога и одну строчку кода. Нам
придется писать программу с использованием функций библиотеки WinInet.dll и заголовочного файла,
соответственно, WinInet.Pas. Сразу пропиши его в uses, а то потом забудешь и начнешь тыкаться,
искать свою ошибку. Так вот, давай для начала попробуем разобраться с самыми необходимыми
функциями, а с остальными ты разберешься сам на msdn.microsoft.com (полный линк давать не
буду, т.к. он ОЧЕНЬ большой). Посмотри там следующие функции: InternetDial, InternetGoOnline
или InternetCrackUrl (думаю, эта функция тебя должна заинтересовать ). Но вернемся к реальности.
У нас на повестке дня следующие функции:
1) function InternetOpen(lpszAgent: PChar; dwAccessType: DWORD;
pszProxyName, lpszProxyBypass: PChar; dwFlags: DWORD): HINTERNET; stdcall;
Она открывает интернет-сессию для приложения. Вот какие у нее аргументы:
lpszAgent - имя программы. Серьезные люди пишут application.exename, а старики - ParamStr(0). На
самом деле это не так важно, программа все равно будет работать.
dwAccessType - способ соединения. Вот его типы:
PRE_CONFIG_INTERNET_ACCESS - как в реестре.
INTERNET_OPEN_TYPE_PRECONFIG_WITH_NO_AUTOPROXY - не юзать internet setup file.
GATEWAY_INTERNET_ACCESS - через шлюз.
CERN_PROXY_INTERNET_ACCESS - через прокси.
lpszProxyName - имя прокси.
lpszProxyBypass - кому не надо использовать проксю.
dwFlags - режим работы. Если ставить INTERNET_FLAG_ASYNC, то будет асинхронный. В данном случае
это только дополнительный напряг, поэтому ставь 0.
2) function InternetOpenUrl(hInet: HINTERNET; lpszUrl: PChar;
lpszHeaders: PChar; dwHeadersLength: DWORD; dwFlags: DWORD;
dwContext: DWORD): HINTERNET; stdcall;
Это функция открывает заданный УРЛ! Ее описание:
hInet - переменная типа HINTERNET. Ее значение возвращает функция InternetOpen.
lpszUrl - собственно сам УРЛ.
lpszHeaders - дополнительные строки в НТТР запросе. Нам они не нужны.
dwHeadersLength - их длина.
dwFlags - их тут больше 10 значений. Вот самое нужное:
INTERNET_FLAG_EXISTING_CONNECT - не создавать для объекта нового соединения.
dwContext - пиши 0.
3) function InternetReadFile(hFile: HINTERNET; lpBuffer: Pointer;
dwNumberOfBytesToRead: DWORD; var lpdwNumberOfBytesRead: DWORD): BOOL; stdcall;
InternetReadFile читает удаленный файл. Если ты знаком со старой доброй ReadFile (или _lRead), то
поймешь сам, а это для тех, кто не знает:
hFile - сюда ты подставляешь значение из предыдущей функции (можно и FtpOpenFile, если тебе это ближе).
lpBuffer - буфер, через него мы будем читать файл. Как ты должен помнить, буфер - это массив. Таким образом,
файл читается кусками, равными размеру этого массива, а у нас он объемом 1024 байта, т.е. один килобайт.
dwNumberOfBytesToRead - какое количество байт необходимо прочесть. Он должен быть равен размеру нашего массива, т.е. 1024.
lpdwNumberOfBytesRead - сколько же действительно байт прочитано.
Если все отлично, то функция возвращает true, иначе - false.
4) function InternetSetFilePointer(hFile: HINTERNET;
lDistanceToMove: Longint; pReserved: Pointer;
dwMoveMethod, dwContext: DWORD): DWORD; stdcall;
Для незнакомых с SetFilePointer поясню. Эта функция сдвигает позицию чтения файла на заданное число байт. Т.е. если тебе
надо прочитать файл не с начала, а с отметки 1000 байт, то пользуйся InternetSetFilePointer.
Вот ее параметры:
hFile - этот параметр уже рассматривался.
lDistanceToMove - на какое количество байт смещать указатель.
pReserved - оставлено до лучших времен, а само значение должно быть равно нулю.
dwMoveMethod - откуда делать смещение:
FILE_BEGIN - с начала.
FILE_END - с конца .
FILE_CURRENT - с текущей позиции.
dwContext - должно быть нулем.
Как ты уже догадался, эта функция и будет обеспечивать нам докачку. Если коннект прервется на о
тметке 1.2 Мб, то мы сможем вернуться на нужную нам позицию. При успешном возврате функция вернет
значение в 1.2 Мб. Но учти, если сервак не поддерживает докачки, то файл придется читать с самого начала.
5) function InternetQueryDataAvailable(hFile: HINTERNET; var lpdwNumberOfBytesAvailable: DWORD;
dwFlags, dwContext: DWORD): BOOL; stdcall;
Она выясняет объем доступных данных, т.е. размер запрашиваемого файла. Пояснения:
hFile - переменная типа HINTERNET. Уже рассматривалась выше.
lpdwNumberOfBytesAvailable - доступные байты.
dwFlags - ставь в 0.
dwContext- здесь также установи 0.
6) function InternetCloseHandle(hInet: HINTERNET): BOOL; stdcall;
В InternetCloseHandle нет ничего сложного. Эта функция просто закрывает интернет-сессию.
Все. С разбором функций мы закончили. Их тебе хватит для написания примитивного гетрайта . А если
ты ознакомишься с MSDN'овскими доками и поймешь работу потоков... Тогда я буду ждать 80% скидки на
твой VasyaExtraGet за 9.99$ . Так что закрывай журнальчик, попей пивка, и садись кодить.
Главное, не убей правильное настроение. Если его пока нет, не расстраивайся, будем писать вместе .
Интерфейс
Кидай на форму два TEdit, четыре TLabel, SaveDialog и 4 Кнопки.
Первые 3 кнопки обзови (параметр "caption"): "Загрузить", "Отмена" и "Выход", а на четвертой поставь 3 точки. Label’ы будут называться так:
label1: "Откуда качать?"
label2: "А куда сохранять?"
label3: "Размер файла:"
label4: "0"
В общем, постарайся соответствовать рисунку 2. На нем все предельно ясно, так что перейдем к самому процессу кодинга.
Кодинг
Для начала добавь в раздел public объявление переменной NADO: boolean; (она нужна для прерывания загрузки), создай событие OnClick для 4-й
кнопки и впиши туда такой код:
IF SaveDialog1.Execute then Edit2.Text:= SaveDialog1.FileName;
Этот код добавлен, чтобы не вводить путь вручную. Теперь посмотри на код в блок-врезке. Попытайся
понять содержимое этого листинга. Понял? Не понял? В общем, набей его в свой проект.
Логика работы программы такая. Сначала мы проверяем наличие заданного файла. Если его нет, то
качаем с нуля, если же он существует, то за начальную позицию для докачки берем размер локального
файла и подставляем это значение в InternetSetFilePointer. Что мы и делаем. Затем циклически
читаем по 1024 байта от интернет-файла, пока не скачаем его целиком. Это и будет конец загрузки.
Хотя, на случай ручного прерывания, впиши в OnClick для 2-й кнопки такой код:
NADO:= FALSE
Все остальное ясно и по комментариям, поэтому я протестирую эту программу и перейду к заключению.
5 МИНУТ - ПОЛЕТ НОРМАЛЬНЫЙ
Я запустил закачку файла, но в середине процесса у меня подло прервалась связь (случайно задел момед ногой,
он упал со стола и выдернулся из сети), за что я и словил известное тебе сообщение. Подняв модем и восстановив коннект,
я запустил докачку и успешно слил файл. Заметь, с весьма неплохой скоростью, а все это благодаря компании майкрософт и нашим с тобой прямым ручкам.
Заключение
Программа получилась очень простой, и в твоих руках возможность довести ее до нужного уровня: убрать цикл в отдельный поток, а иначе
будет тормозить интерфейс, добавить различные прогрессбары и прочую приятную лабуду
(][ об этом писал не раз). Исходники, как всегда, можешь взять на сайте [Только модераторы имеют право видеть эту ссылку] - не будем нарушать традицию.
На этом все. Удачи тебе и до новых встреч в эфире.
Листинг TForm1.BitBtn1Click
procedure TForm1.BitBtn1Click(Sender: TObject);
var F: File;
ResumePos,BufferLen,SumSize: DWORD;
h Session, hURL: HInternet;
Buffer: array[1..1024] of Byte;
err: boolean;
begin
S umSize:=0; ResumePos:=0; //Инициализируемся
AssignFile (F,Edit2.Text); //Свяжемся с файлом
IF FileExists (Edit2.Text) then //Есть ли на диске этот файл
begin
Reset(f,1); //Ах, есть? Откроем!
ResumePos:=FileSize(F); //Откуда докачать
Seek(F, FileSize(F)); //А писать будем в конец
end else ReWrite(f,1); //А раз нет, так создадим
NADO:= TRUE; //Надо качать...
//Открыли сессию
hSession:= InternetOpen('X-Kachalka',PRE_CONFIG_INTERNET_ACCESS,nil,nil,0);
//И наш УРЛ
hURL := InternetOpenURL(hSession,PChar(Edit1.Text),nil,0,0,0);
//Сколько там наш файл весит?
InternetQueryDataAvailable(hURL, SumSize,0,0);
label4.Caption:= IntToStr (SumSize); //Сообщим об этом
if ResumePos>0 then //Если докачиваем,
begin
InternetSetFilePointer(hURL,ResumePos,nil,0,0); //То сместимся
end;
REPEAT //Качаем
err:= InternetReadFile(hURL, @Buffer,SizeOf(Buffer),BufferLen); //Читаем буфер
IF err= false then //Ошибка чтения
begin
ShowMessage ('Произошел облом '); //Сообщим и выходим
exit;
end;
BlockWrite(f, Buffer, BufferLen); //Пишем в файл
Application.Processmessages;
UNTIL (BufferLen= 0) Or (NADO= FALSE); //Качаем, пока не все или надо
ShowMessage ('Успешно загружено!');
end;
GetRight, Reget и Flashget. Их расплодилось великое множество, все они занимают первые места в
рейтингах и продаются за немалые деньги. Так что
давай сегодня напишем свой Reget, и ты сможешь демонстрировать всем знакомым девушкам свою
физиономию в about программы .
Реквизит
Он нам понадобится. Прошли те времена, когда все делалось в два диалога и одну строчку кода. Нам
придется писать программу с использованием функций библиотеки WinInet.dll и заголовочного файла,
соответственно, WinInet.Pas. Сразу пропиши его в uses, а то потом забудешь и начнешь тыкаться,
искать свою ошибку. Так вот, давай для начала попробуем разобраться с самыми необходимыми
функциями, а с остальными ты разберешься сам на msdn.microsoft.com (полный линк давать не
буду, т.к. он ОЧЕНЬ большой). Посмотри там следующие функции: InternetDial, InternetGoOnline
или InternetCrackUrl (думаю, эта функция тебя должна заинтересовать ). Но вернемся к реальности.
У нас на повестке дня следующие функции:
1) function InternetOpen(lpszAgent: PChar; dwAccessType: DWORD;
pszProxyName, lpszProxyBypass: PChar; dwFlags: DWORD): HINTERNET; stdcall;
Она открывает интернет-сессию для приложения. Вот какие у нее аргументы:
lpszAgent - имя программы. Серьезные люди пишут application.exename, а старики - ParamStr(0). На
самом деле это не так важно, программа все равно будет работать.
dwAccessType - способ соединения. Вот его типы:
PRE_CONFIG_INTERNET_ACCESS - как в реестре.
INTERNET_OPEN_TYPE_PRECONFIG_WITH_NO_AUTOPROXY - не юзать internet setup file.
GATEWAY_INTERNET_ACCESS - через шлюз.
CERN_PROXY_INTERNET_ACCESS - через прокси.
lpszProxyName - имя прокси.
lpszProxyBypass - кому не надо использовать проксю.
dwFlags - режим работы. Если ставить INTERNET_FLAG_ASYNC, то будет асинхронный. В данном случае
это только дополнительный напряг, поэтому ставь 0.
2) function InternetOpenUrl(hInet: HINTERNET; lpszUrl: PChar;
lpszHeaders: PChar; dwHeadersLength: DWORD; dwFlags: DWORD;
dwContext: DWORD): HINTERNET; stdcall;
Это функция открывает заданный УРЛ! Ее описание:
hInet - переменная типа HINTERNET. Ее значение возвращает функция InternetOpen.
lpszUrl - собственно сам УРЛ.
lpszHeaders - дополнительные строки в НТТР запросе. Нам они не нужны.
dwHeadersLength - их длина.
dwFlags - их тут больше 10 значений. Вот самое нужное:
INTERNET_FLAG_EXISTING_CONNECT - не создавать для объекта нового соединения.
dwContext - пиши 0.
3) function InternetReadFile(hFile: HINTERNET; lpBuffer: Pointer;
dwNumberOfBytesToRead: DWORD; var lpdwNumberOfBytesRead: DWORD): BOOL; stdcall;
InternetReadFile читает удаленный файл. Если ты знаком со старой доброй ReadFile (или _lRead), то
поймешь сам, а это для тех, кто не знает:
hFile - сюда ты подставляешь значение из предыдущей функции (можно и FtpOpenFile, если тебе это ближе).
lpBuffer - буфер, через него мы будем читать файл. Как ты должен помнить, буфер - это массив. Таким образом,
файл читается кусками, равными размеру этого массива, а у нас он объемом 1024 байта, т.е. один килобайт.
dwNumberOfBytesToRead - какое количество байт необходимо прочесть. Он должен быть равен размеру нашего массива, т.е. 1024.
lpdwNumberOfBytesRead - сколько же действительно байт прочитано.
Если все отлично, то функция возвращает true, иначе - false.
4) function InternetSetFilePointer(hFile: HINTERNET;
lDistanceToMove: Longint; pReserved: Pointer;
dwMoveMethod, dwContext: DWORD): DWORD; stdcall;
Для незнакомых с SetFilePointer поясню. Эта функция сдвигает позицию чтения файла на заданное число байт. Т.е. если тебе
надо прочитать файл не с начала, а с отметки 1000 байт, то пользуйся InternetSetFilePointer.
Вот ее параметры:
hFile - этот параметр уже рассматривался.
lDistanceToMove - на какое количество байт смещать указатель.
pReserved - оставлено до лучших времен, а само значение должно быть равно нулю.
dwMoveMethod - откуда делать смещение:
FILE_BEGIN - с начала.
FILE_END - с конца .
FILE_CURRENT - с текущей позиции.
dwContext - должно быть нулем.
Как ты уже догадался, эта функция и будет обеспечивать нам докачку. Если коннект прервется на о
тметке 1.2 Мб, то мы сможем вернуться на нужную нам позицию. При успешном возврате функция вернет
значение в 1.2 Мб. Но учти, если сервак не поддерживает докачки, то файл придется читать с самого начала.
5) function InternetQueryDataAvailable(hFile: HINTERNET; var lpdwNumberOfBytesAvailable: DWORD;
dwFlags, dwContext: DWORD): BOOL; stdcall;
Она выясняет объем доступных данных, т.е. размер запрашиваемого файла. Пояснения:
hFile - переменная типа HINTERNET. Уже рассматривалась выше.
lpdwNumberOfBytesAvailable - доступные байты.
dwFlags - ставь в 0.
dwContext- здесь также установи 0.
6) function InternetCloseHandle(hInet: HINTERNET): BOOL; stdcall;
В InternetCloseHandle нет ничего сложного. Эта функция просто закрывает интернет-сессию.
Все. С разбором функций мы закончили. Их тебе хватит для написания примитивного гетрайта . А если
ты ознакомишься с MSDN'овскими доками и поймешь работу потоков... Тогда я буду ждать 80% скидки на
твой VasyaExtraGet за 9.99$ . Так что закрывай журнальчик, попей пивка, и садись кодить.
Главное, не убей правильное настроение. Если его пока нет, не расстраивайся, будем писать вместе .
Интерфейс
Кидай на форму два TEdit, четыре TLabel, SaveDialog и 4 Кнопки.
Первые 3 кнопки обзови (параметр "caption"): "Загрузить", "Отмена" и "Выход", а на четвертой поставь 3 точки. Label’ы будут называться так:
label1: "Откуда качать?"
label2: "А куда сохранять?"
label3: "Размер файла:"
label4: "0"
В общем, постарайся соответствовать рисунку 2. На нем все предельно ясно, так что перейдем к самому процессу кодинга.
Кодинг
Для начала добавь в раздел public объявление переменной NADO: boolean; (она нужна для прерывания загрузки), создай событие OnClick для 4-й
кнопки и впиши туда такой код:
IF SaveDialog1.Execute then Edit2.Text:= SaveDialog1.FileName;
Этот код добавлен, чтобы не вводить путь вручную. Теперь посмотри на код в блок-врезке. Попытайся
понять содержимое этого листинга. Понял? Не понял? В общем, набей его в свой проект.
Логика работы программы такая. Сначала мы проверяем наличие заданного файла. Если его нет, то
качаем с нуля, если же он существует, то за начальную позицию для докачки берем размер локального
файла и подставляем это значение в InternetSetFilePointer. Что мы и делаем. Затем циклически
читаем по 1024 байта от интернет-файла, пока не скачаем его целиком. Это и будет конец загрузки.
Хотя, на случай ручного прерывания, впиши в OnClick для 2-й кнопки такой код:
NADO:= FALSE
Все остальное ясно и по комментариям, поэтому я протестирую эту программу и перейду к заключению.
5 МИНУТ - ПОЛЕТ НОРМАЛЬНЫЙ
Я запустил закачку файла, но в середине процесса у меня подло прервалась связь (случайно задел момед ногой,
он упал со стола и выдернулся из сети), за что я и словил известное тебе сообщение. Подняв модем и восстановив коннект,
я запустил докачку и успешно слил файл. Заметь, с весьма неплохой скоростью, а все это благодаря компании майкрософт и нашим с тобой прямым ручкам.
Заключение
Программа получилась очень простой, и в твоих руках возможность довести ее до нужного уровня: убрать цикл в отдельный поток, а иначе
будет тормозить интерфейс, добавить различные прогрессбары и прочую приятную лабуду
(][ об этом писал не раз). Исходники, как всегда, можешь взять на сайте [Только модераторы имеют право видеть эту ссылку] - не будем нарушать традицию.
На этом все. Удачи тебе и до новых встреч в эфире.
Листинг TForm1.BitBtn1Click
procedure TForm1.BitBtn1Click(Sender: TObject);
var F: File;
ResumePos,BufferLen,SumSize: DWORD;
h Session, hURL: HInternet;
Buffer: array[1..1024] of Byte;
err: boolean;
begin
S umSize:=0; ResumePos:=0; //Инициализируемся
AssignFile (F,Edit2.Text); //Свяжемся с файлом
IF FileExists (Edit2.Text) then //Есть ли на диске этот файл
begin
Reset(f,1); //Ах, есть? Откроем!
ResumePos:=FileSize(F); //Откуда докачать
Seek(F, FileSize(F)); //А писать будем в конец
end else ReWrite(f,1); //А раз нет, так создадим
NADO:= TRUE; //Надо качать...
//Открыли сессию
hSession:= InternetOpen('X-Kachalka',PRE_CONFIG_INTERNET_ACCESS,nil,nil,0);
//И наш УРЛ
hURL := InternetOpenURL(hSession,PChar(Edit1.Text),nil,0,0,0);
//Сколько там наш файл весит?
InternetQueryDataAvailable(hURL, SumSize,0,0);
label4.Caption:= IntToStr (SumSize); //Сообщим об этом
if ResumePos>0 then //Если докачиваем,
begin
InternetSetFilePointer(hURL,ResumePos,nil,0,0); //То сместимся
end;
REPEAT //Качаем
err:= InternetReadFile(hURL, @Buffer,SizeOf(Buffer),BufferLen); //Читаем буфер
IF err= false then //Ошибка чтения
begin
ShowMessage ('Произошел облом '); //Сообщим и выходим
exit;
end;
BlockWrite(f, Buffer, BufferLen); //Пишем в файл
Application.Processmessages;
UNTIL (BufferLen= 0) Or (NADO= FALSE); //Качаем, пока не все или надо
ShowMessage ('Успешно загружено!');
end;
Страница 1 из 1
Права доступа к этому форуму:
Вы не можете отвечать на сообщения
Вс Ноя 02 2014, 14:18 автор dimka
» Исходники игр на Паскале
Чт Окт 16 2014, 13:18 автор tqq
» Помогите разблокировать smartbuy micro CD.
Ср Сен 24 2014, 14:40 автор Unearthly
» Исходники программ на Делфи для скачивания
Ср Июл 16 2014, 08:15 автор aleator
» Как прошить телефон Nokia?
Вт Май 06 2014, 12:42 автор vovan17
» Самопроизвольное отключение ноутбука
Вт Июл 09 2013, 21:17 автор Aleksei
» МР3-плеер NEXX nf-810
Пн Июл 01 2013, 09:11 автор Vitaliy_82
» Как снять защиту от записи на MicroSD
Вт Мар 26 2013, 16:25 автор katja*****
» Как передавать большие файлы с одного компьютера на другой быстро?
Пн Окт 01 2012, 20:07 автор irko