Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2007.02.18;
Скачать: CL | DM;

Вниз

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

 
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;
Скачать: CL | DM;

Наверх




Память: 0.57 MB
Время: 0.047 c
15-1169621895
vajo
2007-01-24 09:58
2007.02.18
Ищу файлменеджер


15-1169869363
IMHO
2007-01-27 06:42
2007.02.18
Слово о клавиатуре


2-1170097733
Riply
2007-01-29 22:08
2007.02.18
Использование Result - как переменной в функции.


2-1169580356
serko
2007-01-23 22:25
2007.02.18
Зарегистрировать тип файла


15-1169013501
NLex
2007-01-17 08:58
2007.02.18
FireBird Component