Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Сети";
Текущий архив: 2007.02.18;
Скачать: [xml.tar.bz2];

Вниз

Программа виснет при закачке если меняю фокус на другую   Найти похожие ветки 

 
Elen ©   (2006-09-12 09:27) [0]

Доброго времени суток господа!

Мне нужно было на скорую руку написать простейшую программу
для закачки файлов из инета.
Порывшись на форуме нахожу два способа:

1. Indy

procedure tform1.GetFile(URL, fullfilename: string);
var
str: TFileStream;
begin
try
 str := TFileStream.Create(fullfilename,fmCreate);
 IdHTTP1.Get(URL, str);
finally
 str.Free;
end;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
IdHTTP1.Host :="21.13.4.234"; // это адрес прокси
IdHTTP1.Port :=8080;

IdHTTP1.Connect;

 GetFile("http://podgoretsky.com/ftp/Docs/Delphi/Podgoretsky/bits.doc", "d:\_____.doc");
IdHTTP1.Disconnect;
end;


Этот способ в idhttp.pas выдает ошибку
403 forbidden (The ISA server denied the specified Uniform Recource Locator)
Поскольку времени нет и есть другой способ разбор этой ошибки я оставляю на будущее
но буду благодарна если обьясните.

2. WinInet


//********* PROCEDURE**********
procedure tform1.dload;
//const
Var i:byte;FileName, FileURL:string; Report:textfile;
begin
if not DirectoryExists(appdir+"dload") then aMakeDir(appdir+"dload");
AssignFile(report,appdir+"dload\report.txt");
rewrite(report);
//**************************************************************************
for i:=0 to ListBox1.Count-1 do begin
ListBox1.ItemIndex:=i;
FileURL:=ListBox1.Items[i];
FileName:= appdir+"dload\"+copyas(ListBox1.Items[i],"/",-1);
writeln(report,padr("---Begin on "," ",15)+datetimetostr(now));
hSession := InternetOpen({"STEROID Download}"Microsoft Internet Explorer",
               INTERNET_OPEN_TYPE_PRECONFIG, nil, nil, 0);
if Assigned(hSession) then begin
  hFile := InternetOpenURL(hSession, PChar(FileURL), nil, 0,
      INTERNET_FLAG_RELOAD, 0);
  if Assigned(hFile) then begin
     AssignFile(f, FileName);
     Rewrite(f,1);
     fSize := 0;  
     repeat
        InternetReadFile(hFile, @Buffer, SizeOf(Buffer), BufferLen);
        BlockWrite(f, Buffer, BufferLen);
        fSize := fSize + BufferLen;
        caption:=inttostr(i)+" - "+inttostr(fsize);
     until (BufferLen = 0);
     CloseFile(f);
     writeln(report,filefrompath(filename)+" (",fsize,")");
     writeln(report,padr("---Ending on "," ",15)+datetimetostr(now));writeln(report);
     InternetCloseHandle(hFile);
  end;
  InternetCloseHandle(hSession);
end;

   //**************************************************************************
end;
ListBox1.Items.Clear;
end;
//********* END PROCEDURE*******


Этот способ мне нравится больше так как контроль за закачкой глубже.
И он как раз сработал с первого раза.

Но вот прикол - Пока программа работает на переднем плане все хорошо
но стоит мне переключить фокус на другую прогу и моя виснет безвозмездно.
приходится закрывать ее принудительно и соответственно качка вроде останавливается

С чем это может быть связано?


Я не знаю в какую ветку лучше писать, пишу сюда т.к. все таки связано с сетью,
но не обижусь если модератор перенесет этот вопрос в начинающие.


 
Сергей М. ©   (2006-09-12 09:47) [1]


> С чем это может быть связано?


Например, с возникающими в этот момент в твоей "проге" исключениями.


> способ мне нравится больше так как контроль за закачкой
> глубже


Чем же он "глубже" ?


 
Elen ©   (2006-09-12 09:53) [2]


> Сергей М. ©

Какие там могут быть исключения? ошибки не выдает. Как их отловить?


> Чем же он "глубже" ?


Я могу контролировать каждый блок загрузки, прервать сейчас и докачать потом


 
Сергей М. ©   (2006-09-12 10:01) [3]


> Какие там могут быть исключения?


Да мало ли какие ..

Ты вот даже результат вызова InternetReadFile() игнорируешь, о какой корректности работы программы можно после этого говорить ?


> могу контролировать каждый блок загрузки


Это возможно и при использовании TIdHTTP.


> прервать сейчас и докачать потом


Ой ли ?
Далеко не всякий сервер поддерживает возможность докачки.


 
Elen ©   (2006-09-12 10:19) [4]


> Сергей М. ©

Спасибо. Буду разбираться с Indy.


 
Сергей М. ©   (2006-09-12 10:22) [5]


> Elen ©   (12.09.06 10:19) [4]


Что так сразу ?)

Я ж не хотел тебя пугать, просто обратил внимание на явный потенциальный источник ошибок - игнорирование результата выполнения API-функции..


 
Elen ©   (2006-09-12 10:39) [6]


> Сергей М. ©

Я проверила. InternetReadFile возвращает TRUE. И все равно висячок.


 
Dmitrij_K   (2006-09-12 10:45) [7]


>  InternetReadFile возвращает TRUE. И все равно висячок.

Смешно


 
Elen ©   (2006-09-12 10:48) [8]


> Dmitrij_K

Не очень :-/


 
Сергей М. ©   (2006-09-12 10:49) [9]


> проверила. InternetReadFile возвращает TRUE


А с чего ты взяла, что InternetReadFile будет вызвана всего 1 раз ?

И, я надеюсь, метод dload у тебя вызывается в основном треде ?


 
Dmitrij_K   (2006-09-12 10:50) [10]

Кстати
procedure tform1.GetFile(URL, fullfilename: string);
var
str: TFileStream;
begin
str:=nil; // без этого можно получить AV
try
str := TFileStream.Create(fullfilename,fmCreate);
IdHTTP1.Get(URL, str);
finally
str.Free;
end;
end;


 
Сергей М. ©   (2006-09-12 10:51) [11]


> Dmitrij_K   (12.09.06 10:50) [10]


Ерунду ты городишь


 
Сергей М. ©   (2006-09-12 10:53) [12]


> Dmitrij_K   (12.09.06 10:50) [10]


А, пардон ...
Я не обратил внимания, что конструирование стрима внесено в try-блок


 
Elen ©   (2006-09-12 10:55) [13]


> Сергей М.

InternetReadFile вызывается столько раз сколько ей нужно, пока не вернет пустой буффер. И все эти разы возвращает True, пока я не сменю фокус
Dload в основном потоке и вызывается по нажатию на кнопку. А что многопоточность чревата чем-то плохим?


 
Elen ©   (2006-09-12 10:57) [14]


> Dmitrij_K

Понятно. Учту. Но этот способ не дает AV - предположим я качаю только один файл. Ошибка другая.


 
Dmitrij_K   (2006-09-12 10:58) [15]

Ето еще смешнее. Читать надо для чего какие параметры нужны
procedure TForm1.Button1Click(Sender: TObject);
begin
IdHTTP1.Host :="21.13.4.234"; // это адрес прокси
IdHTTP1.Port :=8080;

IdHTTP1.Connect;

GetFile("http://podgoretsky.com/ftp/Docs/Delphi/Podgoretsky/bits.doc", "d:\_____.doc");
IdHTTP1.Disconnect;
end;


Надо так
 
 IdHTTP1.ProxyParams.ProxyServer := "21.13.4.234";
 IdHTTP1.ProxyParams.ProxyPort   := 8080;
 GetFile("http://podgoretsky.com/ftp/Docs/Delphi/Podgoretsky/bits.doc", "d:\_____.doc");


 
Dmitrij_K   (2006-09-12 10:59) [16]


> Но этот способ не дает AV - предположим я качаю только один
> файл.

Когда-нибудь даст.


 
Elen ©   (2006-09-12 11:05) [17]


> IdHTTP1.ProxyParams.ProxyServer

Что за прикол - там нет таких свойств!? (Я что сегодня еще не проснулась?)


 
Dmitrij_K   (2006-09-12 11:07) [18]

Какая версия Indy?


 
Elen ©   (2006-09-12 11:10) [19]


> Dmitrij_K

Internet Direct for D6 Property and Comonent Editors?
или как версию узнать?


 
umbra ©   (2006-09-12 11:14) [20]


>  Но этот способ не дает AV - предположим я качаю только
> один
>  файл

Поскольку локальные переменные не инициализируются, то AV может случиться, если исключение произойдет при вызове TFileStream.Create, из-за неизбежного вызова Free


 
Elen ©   (2006-09-12 11:15) [21]


> umbra ©

Понятно. Учту.


 
Dmitrij_K   (2006-09-12 11:16) [22]


>  как версию узнать?

Для инди надо нажать правой кнопкой по компаненту на форме
"About Internet Direct (Indy) ..."


 
Elen ©   (2006-09-12 11:21) [23]


> Dmitrij_K

8.0.25 (1993-2001)


 
Dmitrij_K   (2006-09-12 11:30) [24]


> 8.0.25

Ух какое старье.
IdHTTP.ProxyPort
IdHTTP.ProxyServer


 
Сергей М. ©   (2006-09-12 11:39) [25]


> многопоточность чревата чем-то плохим?


А как же !

Ты же к свойствам формы обращаешься в этом методе..

Пробуй так:

    writeln(report, "Начало цикла");
    try
     j := 1;
     repeat
       InternetReadFile(hFile, @Buffer, SizeOf(Buffer), BufferLen);
       BlockWrite(f, Buffer, BufferLen);
       fSize := fSize + BufferLen;
       writeln(report, "Итерация " + IntToStr(j));
       Inc(j);
    until (BufferLen = 0);
    writeln(report, "Конец цикла");
    except
      writeln(report, "Исключение !");        
    end;

Что видишь в файле отчета:


 
Elen ©   (2006-09-12 11:49) [26]


> Dmitrij_K

Даже старее :

IdHTTP1.Request.ProxyServer:="10.10.3.5";
IdHTTP1.Request.ProxyPort :=8080;


так заработало но качать не хочет из-за авторизации прокси. А через WinInet авторизации не просит

Обновлю ка я себе инди...


 
Elen ©   (2006-09-12 11:52) [27]


> Сергей М. ©

Щас спробую


 
Elen ©   (2006-09-12 11:57) [28]


> Сергей М. ©

ОТКУДА ТУТ ТАКИЕ ИСКЛЮЧЕНИЯ!!!???


 
Сергей М. ©   (2006-09-12 11:59) [29]


> Elen ©   (12.09.06 11:57) [28]


Откуда, откуда .. Оттуда !)

Пробуй и приводи сюда достовно текст отчета ..


 
Elen ©   (2006-09-12 12:03) [30]


> Сергей М. ©

Да собсно он короткий :

---Begin on    12.09.2006 10:56:06
Начало цикла
Исключение !
---Begin on    12.09.2006 10:56:08
Начало цикла
Исключение !

список качаемых файлов :

http://podgoretsky.com/ftp/Docs/Delphi/Podgoretsky/bits.doc
http://www.teplocom.msk.ru/doc/klient.pdf
http://podgoretsky.com/ftp/Docs/Internet/IntroIndy/IndyInDepth.pdf


 
Сергей М. ©   (2006-09-12 12:23) [31]


> Elen ©   (12.09.06 12:03) [30]


Вот тебе и исключение !)
А ты - "откуда, откуда .."))..

теперь делай так:

   writeln(report, "Начало цикла");
   try
    j := 1;
    repeat
      InternetReadFile(hFile, @Buffer, SizeOf(Buffer), BufferLen);
      BlockWrite(f, Buffer, BufferLen);
      fSize := fSize + BufferLen;
      writeln(report, "Итерация " + IntToStr(j));
      Inc(j);
   until (BufferLen = 0);
   writeln(report, "Конец цикла");
   except
     on e:exception do writeln(report, "Исключение " + e.classname + " " + e.message);        
   end;

Что видишь в отчете ?


 
umbra ©   (2006-09-12 12:46) [32]


> но качать не хочет из-за авторизации прокси

а у Request нет свойств наподобие ProxyAuthorization, ProxyLogin, ProxyPassword?


 
Elen ©   (2006-09-12 13:01) [33]


> Сергей М. ©

Так кажись ясно - BlockWrite выдает исключение 103 File not open.
буду его копать. Cпасибо за помощь. (Но ведь сохраняло скачанное как-то...)


> umbra ©

Есть ProxyAuthenticate , ProxyPassword, ProxyUsername.


 
Сергей М. ©   (2006-09-12 13:05) [34]


> Но ведь сохраняло скачанное как-то...


Не знаю уж, что у тебя там куда "сохраняло", но со сменой фокуса это никак не связано)


 
umbra ©   (2006-09-12 13:18) [35]


> Есть ProxyAuthenticate , ProxyPassword, ProxyUsername.
>

если у Вас на прокси используется Basic-аутентификация, то пропишите имя пользователя прокси и его пароль в св-ва ProxyUsername и ProxyPassword соответственно.


 
Elen ©   (2006-09-12 13:19) [36]


> Сергей М. ©

  AssignFile(f, FileName);
  Rewrite(f,1);
  writeln(report, "Начало цикла");
  try
    j := 1;
    repeat
      InternetReadFile(hFile, @Buffer, SizeOf(Buffer), BufferLen);
      BlockWrite(f, Buffer, BufferLen);
      fSize := fSize + BufferLen;
      writeln(report, "Итерация " + IntToStr(j));
      Inc(j);
     Application.Title:=inttostr(i)+"["+IntToStr(j)+"] - "+inttostr(fsize);
   until (BufferLen = 0);
   writeln(report, "Конец цикла");
   except
          on e:exception do writeln(report, "Исключение " + e.classname + " " + +e.message);
   end;


Как оказалось качка идет нормально, но отображение на экране (Application.Title:=inttostr(i)+"["+IntToStr(j)+"] - "+inttostr(fsize);) с момента смены фокуса не обновляется и прога не отвечает. Но стоит ей закончить качку как все отображается коректно и BlockWrite оказался непричем.

Ну значит все в порядке. можно оставлять на ночь.


 
Elen ©   (2006-09-12 13:22) [37]


> umbra ©

Спасибо. Попробую.


 
Сергей М. ©   (2006-09-12 13:25) [38]


> Как оказалось качка идет нормально


Тогда в [30] и [33] ты вешала лапшу)


 
Elen ©   (2006-09-12 13:32) [39]


> Сергей М. ©

Sorry, верно, Я только потом заметила отсутствие

AssignFile(f, FileName);
Rewrite(f,1);

С которыми был связан BlockRead.
Не обижайтесь. ;-)


 
Сергей М. ©   (2006-09-12 13:39) [40]


> Elen ©   (12.09.06 13:32) [39]


Ну а касаемо контроля хода закачки средствами IdHTTP.Get -  вторым параметром укажи своего TFileStream-наследника, у которого перекрыт вирт.метод Write().



Страницы: 1 2 вся ветка

Форум: "Сети";
Текущий архив: 2007.02.18;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.56 MB
Время: 0.047 c
2-1170052000
anonimousC++
2007-01-29 09:26
2007.02.18
Вопрос по си++, знаю что это форум по Делфи...


4-1160074863
electric
2006-10-05 23:01
2007.02.18
HOOK на мышь


2-1170276381
Wlad_M
2007-01-31 23:46
2007.02.18
Как вписать недостающий класс в экзешник


3-1164181397
bogdan_inc
2006-11-22 10:43
2007.02.18
из Excel в MSSQL


15-1169897718
dmdel
2007-01-27 14:35
2007.02.18
firebird 2.0





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский