AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Code-Bibliothek Library: Internet / LAN / ASP.NET Delphi Datei über idHTTP mit Fortschrittsanzeige downloaden
Thema durchsuchen
Ansicht
Themen-Optionen

Datei über idHTTP mit Fortschrittsanzeige downloaden

Ein Thema von gsh · begonnen am 19. Jun 2005
Antwort Antwort
Benutzerbild von gsh
gsh

Registriert seit: 24. Okt 2004
1.542 Beiträge
 
Delphi XE Architect
 
#1

Datei über idHTTP mit Fortschrittsanzeige downloaden

  Alt 19. Jun 2005, 11:09
Servus

In meinem ersten und hoffentlich nicht letzten Beitrag in der Code-Library wollte ich euch meine Problemmlösung für das herunterladen einer Datei mit der Indy komponente idHTTP anbieten. Dieser Code ladet eine Datei aus dem Internet mit einer Geschindigkeitsanzeige und einer Fortschrittsanzeige. Außerdem ist der Code fähig mit oder ohne der Dateigröße die datei herunterzuladen.

Also auf dem Formular brauchen wir:
Eine Fortschrittsanzeige:

Name: Progress
Typ: TProgressBar
Zwei Labels:
Name: SpeedLabel
Typ: TLabel
Name: Status
Typ: TLabel
Einen Button zum starten:
Name: Button1
Typ: TButton
Möglicher weiße noch zwei Edtis für die Datei angaben
Name: Edit1
Typ: TEdit
Name: Edit2
Typ: TEdit
Und noch die Indy-Komponente:
Name: IdHTTP
Typ: TIdHTTP

Globale Variablen:
Delphi-Quellcode:
  private
    { Private-Deklarationen }
    FTime: Longword; //Beide Variablen werden für die kb/sec anzeige gebraucht
    FBytes: Longword; // --"--
  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;

const
  cFileSplitSize : Int64 = 40*1024; //40 KB größe stücke wird die Datei zerhackt
So nun zum Code:

Als erstes den Code der einfach die unschöne Byte zahl in eine schöne zahl mit identifer schreibt (zb. anstatt 1024 => 1 KB schreibt)
Delphi-Quellcode:
function GetSizeName(const Size : Int64): String;
begin
  if Size <= -1 then
    Result := 'Unbekannt ('+IntToStr(Size)+')'
  else
  if Size < 1024 then
    Result := inttostr(Size)+' Byte'
  else
  if Size < 1048576 then
    Result := Format('%.2f',[Size/1024])+' KiB'
  else
  if Size < 1073741824 then
    Result := Format('%.2f',[Size/1048576])+' MiB'
  else
  if Size < 1099511627776 then
    Result := Format('%.2f',[Size/1073741824])+' GiB'
  else
  if Size < 1125899906842624 then
    Result := Format('%.2f',[Size/1099511627776])+' TiB'
  else
  Result := Format('%.2f',[Size/1125899906842624])+' PiB';
end;
Diesen Code brauchen wir für die kb/sec anzeige:
Delphi-Quellcode:
procedure THaupt.IdHTTPWorkBegin(ASender: TObject; AWorkMode: TWorkMode;
  AWorkCountMax: Integer);
begin
  FTime := GetTickCount;
  FBytes := 0;
  Application.ProcessMessages;
end;

procedure TForm1.IdHTTPWork(ASender: TObject; AWorkMode: TWorkMode;
  AWorkCount: Integer);
begin
  if not((GetTickCount - FTime) <= 0) then
  begin
    try
      SpeedStatus.caption := Format('%.2f KB/s', [(AWorkCount - FBytes) / (GetTickCount - FTime)]);
    except
    end;
  end;
  FTime := GetTickCount;
  FBytes := AWorkCount;
  Application.ProcessMessages;
end;
Am Schluss kommen wir jetzt zum eigentlichen Code der die Datei downloadet
Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
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(Edit1.Text);
  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(Edit2.Text, fmCreate or fmShareDenyNone);
    try
      //und "normal" herunterladen
      idHTTP.Get(Edit1.Text, lStream);
    finally
      if Assigned(lStream) then lStream.Free; //FileStream freigeben wenn gesetzt
    end;
    //Alles auf fertig stellen
    Status.Caption := 'Fertig';
    SpeedStatus.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(Edit2.Text, fmCreate or fmShareDenyNone);
  lStream.Position := 0;
  try
    repeat
      // Damit sich das Programm nicht aufhängt
      Application.ProcessMessages;

      //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.Range := Format('%d-%d', [BytesKopiert, (BytesKopiert+cFileSplitSize-1)]);
      end
      else IdHttp.Request.Range := Format('%d-', [BytesKopiert]);

      Application.ProcessMessages;
      //Den eingesttelten Teil herunterladen und ihn die Datei speichern
      IdHTTP.Get(Edit1.Text, 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
    IdHttp.Request.Range := ''; //Verhindert das die nächste Anfrage in einem 206 Fehler endet
  end;
  //Alles auf fertig stellen
  Status.Caption := 'Fertig';
  SpeedStatus.caption := 'Fertig';
  Progress.Position := 100;
end;
Ich hoffe ich konnte jemanden helfen

[edit=JasonDX] Cache refreshed (fuer Syntaxhighlighting); Mfg, JasonDX[/edit]
[edit=Matze]Korrektur hinzugefügt. Mfg, Matze[/edit]
[edit=Matze] Mfg, Matze[/edit]
[edit=Phoenix]Korrektur hinzugefügt. Mfg, Phoenix[/edit]
[edit=JasonDX]Ebenfalls Korrektur hinzugefügt. Mfg, JasonDX[/edit]
[edit=Daniel]Auf Wunsch des Autors neue Fassung der Funktion "GetSizeName" eingefügt. Mfg, Daniel[/edit]
Alex
"Sage nicht alles, was du weißt, aber wisse alles, was du sagst!" Matthias Claudius
"Wer sich über Kritik ärgert, gibt zu, daß er sie verdient hat." Tacitus

Geändert von Daniel (17. Aug 2010 um 09:02 Uhr)
  Mit Zitat antworten Zitat
Antwort Antwort

Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 15:02 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz