![]() |
Datei über idHTTP mit Fortschrittsanzeige downloaden
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:
So nun zum Code:
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 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:
Diesen Code brauchen wir für die kb/sec anzeige:
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;
Delphi-Quellcode:
Am Schluss kommen wir jetzt zum eigentlichen Code der die Datei downloadet
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;
Delphi-Quellcode:
Ich hoffe ich konnte jemanden helfen :mrgreen:
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; [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] |
Alle Zeitangaben in WEZ +1. Es ist jetzt 16:38 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz