Конференция "Начинающим" » Докачка файлов через idhttp. [D7, WinXP]
 
  • vegarulez (23.05.10 22:45) [0]
    Привет всем мастерам!
    Возникла задача скачивания файлов из интернета.
    Скачал довольно хороший пример.

    delphi.int.ru/download/file/257/


    но там нет такого нужного момента как докачка файла, при разрыве соединения.
    Полазил в интернете и нашёл ещё пример

    delphisources.ru/pages/sources/internet/2005_year/download_plus.html



    но он не компилиться под d7+indy10.1.5
    Прошу помочь с этим вопросом.

    Почитал статьи в интернете, и скачал пару примеров с использованием WinInet.

    delphisources.ru/pages/faq/base/download_with_download_again.html


    Там используется такой параметр как range, используя его в заголовке idhhtp можно организовать докачку, но тут вопрос метод get при обращении на скачивание файла скидывает в поток поток пишет в файл. Тут просто у меня не понимание - как продолжить дописывать файл при разрыве соединения и организации повторного закачивания?
  • vegarulez (23.05.10 22:55) [1]
    для первого примера - описание delphi.int.ru/articles/39/

    Второй пример не компилиться в юните uThreads ругается на  строку
    HTTP.OnWork := OnWork;


    ошибку выводит:
    incompatible types: 'Parameters lists differ'
    Посомтрел в первом примере - там впринципе также работа с onwork происходит... подскажите что может быть не так???
  • Медвежонок Пятачок © (23.05.10 23:20) [2]
    скзано же по-русски:
    incompatible types: 'Parameters lists differ'

    текущая версия инди имеет другой список параметров обработчика OnWork по сравнению с компилируемым примером.
  • vegarulez (23.05.10 23:23) [3]
    Список тот же, которые в процедуре обработчика... что в первом примере что во втором
  • vegarulez (23.05.10 23:25) [4]
    хотя не... разница увидена
    Sender : TObject;
    и
    ASender : TObject;
  • vegarulez (23.05.10 23:28) [5]
    Хотя не... всё там также (
  • vegarulez (23.05.10 23:42) [6]
    Нашёл. Поменял. 2-ой пример запустился.
  • vegarulez (24.05.10 00:19) [7]
    только докачка в том понимании в каком она должна быть - не пашет (
  • Медвежонок Пятачок © (24.05.10 00:19) [8]
    Список тот же, которые в процедуре обработчика.

    Если бы он был тот же, то не было бы
    incompatible types: 'Parameters lists differ'
  • Плохиш © (24.05.10 10:41) [9]

    > Там используется такой параметр как range, используя его
    > в заголовке idhhtp можно организовать докачку, но тут вопрос
    > метод get при обращении на скачивание файла скидывает в
    > поток поток пишет в файл. Тут просто у меня не понимание
    > - как продолжить дописывать файл при разрыве соединения
    > и организации повторного закачивания?

    Поток, в который скидывают, никуда сам ничего не пишет. Т.ч. надо просто написать часть программы, которая записывает полученные данные в файл на нужное место.
  • vegarulez (26.05.10 12:24) [10]
    TFileStream.Create(ToFolder, fmCreate);

    А файл уже есть, допустим часть скачена уже. Не знаю как правильно сделать чтобы поток TFileStream приклеил к уже существующему файлу следющую часть...

    думаю сделать так - проверять есть ли файл, если нет - то запрашивать его размер и качать по частям через range, далее эти части "склеивать" между собой. Ну сообствено зная стандартный размер части будет понятно скачалась она полностью или нет, взависимости от этого переходить к скачиванию следующей части.
  • Palladin © (26.05.10 12:31) [11]
  • Плохиш © (26.05.10 12:34) [12]
    1. Запроси размер файла
    2. Создай filestream требуемого размера
    3. пиши каждую принятую часть в соответствующее место стрима.

    PS. из [9] "надо просто написать часть программы, которая записывает полученные данные в файл на нужное место."
  • vegarulez (27.05.10 17:19) [13]
    пока что пытаюсь сделать без потока, просто пробую... натыкаюсь на ряд не понятных моментов.

    Почему то при докачивании, по идее перемещаю указатель в то место где поток оборвался, но смотрю он увеличивает размер файла ровно в 2 раза... и при скачивании ествсвенно не читабельный... нинаю... как быть

    Подскажите, где что не так...

    Думаю может в
    IdHTTP1.OnWork передвигать указатель tfilestream, но это как то муторно... подскажите плиз.

    procedure TForm1.Button3Click(Sender: TObject);
    var
    IdHTTP1:TidHttp;
    SourceFileSize: Dword;
    FileDate: TDateTime;
    SourceFile, SourceURL,FileType: string;
    fDownloadStream: TFileStream;
    begin
    SourceFile:=Edit2.Text;
    SourceURL := Edit1.Text;
    IdHTTP1:=TIdHTTP.Create(nil);
    IdHTTP1.ProtocolVersion := pv1_1;
    IdHTTP1.HandleRedirects := True;
    IdHTTP1.Head(SourceURL);
    SourceFile := IdHTTP1.URL.Document;
    SourceFileSize := IdHTTP1.Response.ContentLength;
    FileDate := IdHTTP1.Response.LastModified;
    FileType := IdHTTP1.Response.ContentType;
    if FileExists(IdHTTP1.URL.Document) then
    begin
    fDownloadStream := TFileStream.Create(SourceFile, fmOpenReadWrite);
    Idhttp1.Request.Range:=Format('%d-%d',[fDownloadStream.Position,
    SourceFileSize-1]);
    fDownloadStream.Seek(SourceFileSize,soFromBeginning);
    end
    else
    begin
    fDownloadStream := TFileStream.Create(SourceFile, fmCreate);
    fDownloadStream.Seek(0,soFromBeginning); //
    end;
    IdHTTP1.Request.ContentType := FileType;
    IdHTTP1.Request.ContentRangeStart := fDownloadStream.Position;
    IdHTTP1.Request.ContentRangeEnd := SourceFileSize;
    IdHTTP1.Get(SourceURL,fDownloadStream);
    fDownloadStream.Free;
    IdHTTP1.Free;
    end;

  • vegarulez (27.05.10 17:19) [14]
    пока разбираюсь пробую без потоков (Tthread).
  • Медвежонок Пятачок © (27.05.10 17:28) [15]
    но смотрю он увеличивает размер файла ровно в 2 раза.

    один и тот же файл скачан 2 раза.
    все принятые байты записаны в один и тот же локальный файл.
  • vegarulez (27.05.10 21:07) [16]
    Да я понимаю. но почему он не перемещает указатель потока при помещении в файл. постпенно. а сразу выделет место на диске под весь файл? т.е. грубо говоря, файл не меняетет свой размер он сразу создаётся того размера, который должен быть уже после полного скачивания, но по сути вещей он только начинает его качать.
    при каждом повторном запуске он опять приклеивает к файлу его размер, и так какждый раз при каждом следующем запуске, хотя реально скачивание только началось...
    указатель на размер файла вроде почитав про это перемещаю в начало... и при повторном скачивании тоже смотрю сколько скачал, чтоб поставить указатель...
    fDownloadStream.Seek(SourceFileSize,soFromBeginning);

    но почему то этого не происходит (

    подскажите как быть ...
  • Медвежонок Пятачок © (27.05.10 22:30) [17]
    кто "он"?

    и почему "он" должен что-то перемещать?
    перемещать должен программист.

    при каждом повторном запуске он опять приклеивает к файлу его размер

    Все в полном соответствии как ты и просил.
    Локальный файл открыт, указатель смещен в конец.
    Далее с сервера еще раз запрошен скачиваемый файл.
    Он благополучно скачивается как и просилось тобой.
    Все скачанные байты записываются в стрим с текущей позиции указателя.

    Все как ты и просил (точнее как ты и запрограммировал).

    подскажите как быть ...

    и быть или не быть вообще.
  • Anatoly Podgoretsky © (28.05.10 07:16) [18]
    > vegarulez  (27.05.2010 21:07:16)  [16]

    Это ошибка генофонда, он должен был не увеличивать его, а ставить равным или
    вообще наращивать по мере необходимости. Пиши своего наследника с
    исправленым функционалом или переходи на другие компоненты.
  • vegarulez (28.05.10 08:15) [19]
    Медвежонок Пятачок ©   (27.05.10 22:30) [17]
    Anatoly Podgoretsky ©   (28.05.10 07:16) [18]
    премного благодарен за развёрнутые ответы, и описание личности...
    а по существу вопроса?

    Указатель перемещён, всё замечательно - но файл то только начинает скачиваться и я его тут же обрубаю - т.е. грубо говоря скачалось 200 кбайт а на диске уже создан файл в 10 мб. Я вот это не могу понять. Почему создаётся сразу файл размером со скачиваемый файл, когда скачалось всего 200 кб?

    Локальный файл открыт, указатель смещен в конец.

    ну как же так? я же его помещаю в начало:
    fDownloadStream := TFileStream.Create(SourceFile, fmCreate);
    fDownloadStream.Seek(0,soFromBeginning);



    Понимаю, что что-то не до понимаю. Прошу без сарказма указать путь истинный :)
 
Конференция "Начинающим" » Докачка файлов через idhttp. [D7, WinXP]
Есть новые Нет новых   [118411   +35][b:0][p:0.002]