![]() |
Probleme mit 'IdHTTP + Fortschrittsanzeige' aus CodeLibrary
Ich war so frech aus folgendem CodeLibrary-Eintrag die Routine zu übernehmen um bei einem Dateidownload die Geschwindigkeit anzuzeigen:
![]() Leider treten dabei 2 verschiedene Probleme auf. Ich teste jedes Mal mit einer 4MB großen zip-Datei Wenn ich es auf dem lokalen Server teste, dann steht kurz nach dem Start des Download 'fertig' da, dabei wurden nur 120kb runtergeladen Beim Test auf dem Remote-Server kriege ich an unterschiedlichen Zeitpunkten eine 'Connection Closed Gracefully'-Exception. Ich benutze Delphi 2009 mit Indy 10. Hier ist der Code meiner Unit:
Delphi-Quellcode:
unit AutoUpdateUnit;
interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, ComCtrls, IdBaseComponent, IdComponent, IdTCPConnection, IdTCPClient, IdHTTP, StdCtrls; type TAutoUpdateForm = class(TForm) AutoUpdateProgress: TProgressBar; HTTPAutoUpdate: TIdHTTP; SpeedStatus: TLabel; AutoUpdateStatus: TLabel; procedure HTTPAutoUpdateWorkBegin(ASender: TObject; AWorkMode: TWorkMode; AWorkCountMax: Int64); procedure HTTPAutoUpdateWork(ASender: TObject; AWorkMode: TWorkMode; AWorkCount: Int64); procedure DoAutoUpdate(fileName:String); private { Private-Deklarationen } FTime: Longword; //Beide Variablen werden für die kb/sec anzeige gebraucht FBytes: Longword; // --"-- public { Public-Deklarationen } end; var AutoUpdateForm: TAutoUpdateForm; const cFileSplitSize : Int64 = 40*1024; //40 KB größe stücke wird die Datei zerhackt 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 TAutoUpdateForm.DoAutoUpdate(fileName:String); var BytesKopiert, BytesInsgesamt : int64; lStream: TFileStream; RemotePath: String; begin RemotePath:='http://localhost/'; self.Show; self.BringToFront; //Initialiesieren AutoUpdateStatus.Caption := ''; BytesKopiert := 0; AutoUpdateProgress.Position := 0; //In edit 1 steht die downzuladene Datei (z.b. [url]http://www.server.com/datei.dat[/url]) AutoUpdateStatus.Caption := 'Prüfe Header'; // Durch die zwei nächsten Befehle wird die Größe ermittelt und ihn der Variable BytesInsgesamt abgespeichert HTTPAutoUpdate.Head(RemotePath+fileName); BytesInsgesamt := HTTPAutoUpdate.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 AutoUpdateStatus.Caption := 'Normalles herunterladen'; AutoUpdateStatus.Caption := 'Erstelle Datei'; //In Edit 2 steht welche Datei (z.b. C:\datei.dat) //Datei erstellen lStream:=TFileStream.Create(ExtractFilePath(Application.ExeName)+fileName, fmCreate or fmShareDenyNone); try //und "normal" herunterladen HTTPAutoUpdate.Get(RemotePath+fileName, lStream); finally if Assigned(lStream) then lStream.Free; //FileStream freigeben wenn gesetzt end; //Alles auf fertig stellen AutoUpdateStatus.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. AutoUpdateProgress.Max := BytesInsgesamt; AutoUpdateStatus.Caption := 'Erstelle Datei'; //In Edit 2 steht welche Datei (z.b. C:\datei.dat) //Datei erstellen lStream:=TFileStream.Create(ExtractFilePath(Application.ExeName)+fileName, 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 HTTPAutoUpdate.Request.Range := Format('%d-%d', [BytesKopiert, (BytesKopiert+cFileSplitSize-1)]); end else HTTPAutoUpdate.Request.Range := Format('%d-', [BytesKopiert]); Application.ProcessMessages; //Den eingesttelten Teil herunterladen und ihn die Datei speichern HTTPAutoUpdate.Get(RemotePath+fileName, lStream); //Progress und Status aktualliesieren AutoUpdateProgress.Position := BytesKopiert; AutoUpdateStatus.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 HTTPAutoUpdate.Request.Range := ''; //Verhindert das die nächste Anfrage in einem 206 Fehler endet end; //Alles auf fertig stellen AutoUpdateStatus.Caption := 'Fertig'; SpeedStatus.caption := 'Fertig'; AutoUpdateProgress.Position := 100; end; procedure TAutoUpdateForm.HTTPAutoUpdateWork(ASender: TObject; AWorkMode: TWorkMode; AWorkCount: Int64); 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; procedure TAutoUpdateForm.HTTPAutoUpdateWorkBegin(ASender: TObject; AWorkMode: TWorkMode; AWorkCountMax: Int64); begin FTime := GetTickCount; FBytes := 0; Application.ProcessMessages; end; end. |
AW: Probleme mit 'IdHTTP + Fortschrittsanzeige' aus CodeLibrary
Habe auch das selbe Problem.
Hat wer eine Idee? Danke |
AW: Probleme mit 'IdHTTP + Fortschrittsanzeige' aus CodeLibrary
Ohne jetzt vor Delphi zu sitzen... beim Kochen und ohne zu testen *gg* aber als Ansatz gedacht... du kannst auch die Statusanzeige in diesem Fall gleicht direkt in die repeat Schleife einbauen...
Delphi-Quellcode:
fTime := GetTickCount;
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 HTTPAutoUpdate.Request.Range := Format('%d-%d', [BytesKopiert, (BytesKopiert+cFileSplitSize-1)]); end else HTTPAutoUpdate.Request.Range := Format('%d-', [BytesKopiert]); Application.ProcessMessages; //Den eingesttelten Teil herunterladen und ihn die Datei speichern HTTPAutoUpdate.Get(RemotePath+fileName, lStream); //Progress und Status aktualliesieren AutoUpdateProgress.Position := BytesKopiert; AutoUpdateStatus.Caption := GetSizeName(BytesKopiert)+'/'+GetSizeName(BytesInsgesamt); //BytesKopiert weiter setzen BytesKopiert := BytesKopiert+cFileSplitSize; // jetzt Status aktualisieren if (GetTickCount - FTime) > 0) then begin SpeedStatus.caption := Format('%.2f KB/s', [BytesKopiert / (GetTickCount - FTime)]); FTime := GetTickCount; end; until (BytesKopiert >= BytesInsgesamt); //Schleife beenden wenn datei fertig |
Alle Zeitangaben in WEZ +1. Es ist jetzt 00:53 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