Einzelnen Beitrag anzeigen

Hybrid

Registriert seit: 29. Okt 2005
7 Beiträge
 
#1

Indy Http Download+Fortschritt als Funktion geht nicht

  Alt 19. Apr 2006, 17:44
Hallo erstmal.

Ich habe ein Problem mit diesem Beispiel
http://www.delphipraxis.net/internal...ct.php?t=56872

Ich wollte jetzt nicht den Library Eintrag mit Fragen vollspammen.

Wenn ich aus dem Source der Beim Button-OnClick ausgeführt wird eine neue Prozedur mache und diese dann mit einem Button zweimal hintereinander ausführe bekomm ich immmer einen ReadTimeout vom idHttp.
Wenn ich allerdings nur eine Datei zum Download angebe und dann zweimal auf den Button klicke, geht es...

Sieht vielleicht jemand wo das Problem liegt?


Tut mir Leid wegen dem riesigen Source-Block, aber man kann ja zur Not auch auf "Zusammenfalten" klicken


Hier der Source:
Delphi-Quellcode:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ComCtrls, StdCtrls, IdBaseComponent, IdComponent,
  IdTCPConnection, IdTCPClient, IdHTTP;

type
  THaupt = class(TForm)
    IdHTTP: TIdHTTP;
    Status: TLabel;
    SpeedLabel: TLabel;
    Progress: TProgressBar;
    Button1: TButton;
    procedure IdHTTPWork(Sender: TObject; AWorkMode: TWorkMode;
      const AWorkCount: Integer);
    procedure IdHTTPWorkBegin(Sender: TObject; AWorkMode: TWorkMode;
      const AWorkCountMax: Integer);
    procedure Download(AFile :String);
    procedure Button1Click(Sender: TObject);
  private
    { Private-Deklarationen }
    FTime: Longword; //Beide Variablen werden für die kb/sec anzeige gebraucht
    FBytes: Longword; // --"--
  public
    { Public-Deklarationen }
  end;

var
  Haupt: THaupt;

const
  cFileSplitSize : Int64 = 40*1024; //40 KB größe stücke wird die Datei zerhackt
  URL = 'Http://IrgendWoImNetz/';

implementation

{$R *.dfm}

function GetSizeName(const Size : int64): String;
begin
  Result := 'Fehler';
  if Size = -1 then exit;
  if Size < 1024 then
  begin
    Result := inttostr(Size)+' Byte';
    exit;
  end;
  if (1024 <= Size) and (Size < 1048576) then
  begin
    Result := floattostr((round((Size/1024)*100))/100)+' KB';
    exit;
  end;
  if (1048576 <= Size) and (Size < 1099511627776) then
  begin
    Result := floattostr((round((Size/1048576)*100))/100)+' MB';
    exit;
  end;
  if Size > 1099511627776 then
  begin
    Result := floattostr((round((Size/1099511627776)*100))/100)+' GB';
  end;
end;

procedure THaupt.IdHTTPWorkBegin(Sender: TObject; AWorkMode: TWorkMode;
      const AWorkCountMax: Integer);
begin
  FTime := GetTickCount;
  FBytes := 0;
  Application.ProcessMessages;
end;

procedure THaupt.IdHTTPWork(Sender: TObject; AWorkMode: TWorkMode;
      const AWorkCount: Integer);
begin
  if not((GetTickCount - FTime) <= 0) then
  begin
    try
      SpeedLabel.caption := Format('%.2f KB/s', [(AWorkCount - FBytes) / (GetTickCount - FTime)]);
    except
    end;
  end;
  FTime := GetTickCount;
  FBytes := AWorkCount;
  Application.ProcessMessages;
end;

procedure THaupt.Download(AFile :String);
var
  BytesKopiert, BytesInsgesamt : int64;
  lStream: TFileStream;
begin
  //Initialiesieren
  Status.Caption := '';
  BytesKopiert := 0;
  Progress.Position := 0;
  //In edit 1 steht die downzuladene Datei (z.b. [url]http://www.server.com/datei.dat[/url])
  Status.Caption := 'Prüfe Header';
  // Durch die zwei nächsten Befehle wird die Größe ermittelt und ihn der Variable BytesInsgesamt abgespeichert
  IdHTTP.Head(URL+AFile);
  BytesInsgesamt := IdHTTP.Response.ContentLength;
  //Wenn die Indy Komponente -1 zurückgibt dann bedeutet es des der die Dateigröße nicht zu verfügung
  //stellt uns somit kann die Datei ganz normall heruntergeladen werden (ohne Fortschrittsanzeige)
  if BytesInsgesamt = -1 then
  begin
    Status.Caption := 'Normalles herunterladen';
    Status.Caption := 'Erstelle Datei';
    //In Edit 2 steht welche Datei (z.b. C:\datei.dat)
    //Datei erstellen
    lStream:=TFileStream.Create('.\'+AFile, fmCreate or fmShareDenyNone);
    try
      //und "normal" herunterladen
      idHTTP.Get(URL+AFile, lStream);
    finally
      if Assigned(lStream) then lStream.Free; //FileStream freigeben wenn gesetzt
    end;
    //Alles auf fertig stellen
    Status.Caption := 'Fertig';
    SpeedLabel.caption := 'Fertig';
    exit;
  end;
  //Also wenn wir hier angelangt sind dann bedeutet es der Server hat uns die Dateigröße zur Verfügung gestellt.
  Progress.Max := BytesInsgesamt;
  Status.Caption := 'Erstelle Datei';
  //In Edit 2 steht welche Datei (z.b. C:\datei.dat)
  //Datei erstellen
  lStream:=TFileStream.Create('.\'+AFile, fmCreate or fmShareDenyNone);
  lStream.Position := 0;
  try
    repeat
      // Damit sich das Programm nicht aufhängt
      Application.ProcessMessages;
      //Nun setzen wir den Start nach die bereits kopierten Bytes
      IdHTTP.Request.ContentRangeStart := BytesKopiert;
      //Hier wird gebrüft ob die restlichen Bytes größer sind als cFileSplitSize
      if (BytesInsgesamt-BytesKopiert) > cFileSplitSize then
      begin
        //Hier wird einmal die cFileSplitSize eingestellt
        IdHTTP.Request.ContentRangeEnd := BytesKopiert+cFileSplitSize-1;
      end
      //Den rest der Datei
      else IdHTTP.Request.ContentRangeEnd := BytesInsgesamt;
      Application.ProcessMessages;
      //Den eingesttelten Teil herunterladen und ihn die Datei speichern
      IdHTTP.Get(URL+AFile, lStream);
      //Progress und Status aktualliesieren
      Progress.Position := BytesKopiert;
      Status.Caption := GetSizeName(BytesKopiert)+'/'+GetSizeName(BytesInsgesamt);
      //BytesKopiert weiter setzen
      BytesKopiert := BytesKopiert+cFileSplitSize;
    until (BytesKopiert >= BytesInsgesamt); //Schleife beenden wenn datei fertig
  finally
    if Assigned(lStream) then lStream.Free; //FileStream freigeben wenn gesetzt
  end;
  //Alles auf fertig stellen
  Status.Caption := 'Fertig';
  SpeedLabel.caption := 'Fertig';
  Progress.Position := 100;
end;

procedure THaupt.Button1Click(Sender: TObject);
begin
  download('DateiNr1'); // Meine Dateien sind im Schnitt 500KB groß
  download('DateiNr2');
end;

end.
Schonmal danke für die Hilfe.
  Mit Zitat antworten Zitat