AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Netzwerke Delphi Probleme mit 'IdHTTP + Fortschrittsanzeige' aus CodeLibrary
Thema durchsuchen
Ansicht
Themen-Optionen

Probleme mit 'IdHTTP + Fortschrittsanzeige' aus CodeLibrary

Ein Thema von Hedge · begonnen am 19. Nov 2009 · letzter Beitrag vom 18. Jun 2011
Antwort Antwort
Hedge

Registriert seit: 30. Jun 2007
278 Beiträge
 
Delphi 2009 Professional
 
#1

Probleme mit 'IdHTTP + Fortschrittsanzeige' aus CodeLibrary

  Alt 19. Nov 2009, 19:14
Ich war so frech aus folgendem CodeLibrary-Eintrag die Routine zu übernehmen um bei einem Dateidownload die Geschwindigkeit anzuzeigen: http://www.delphipraxis.net/internal...ct.php?t=56872

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.
٩๏̯͡๏)۶
  Mit Zitat antworten Zitat
StoRmtec

Registriert seit: 6. Jan 2003
209 Beiträge
 
#2

AW: Probleme mit 'IdHTTP + Fortschrittsanzeige' aus CodeLibrary

  Alt 17. Jun 2011, 23:37
Habe auch das selbe Problem.
Hat wer eine Idee?

Danke
  Mit Zitat antworten Zitat
Benutzerbild von Daniela.S
Daniela.S

Registriert seit: 1. Mär 2008
Ort: Niederösterreich
226 Beiträge
 
Delphi XE4 Enterprise
 
#3

AW: Probleme mit 'IdHTTP + Fortschrittsanzeige' aus CodeLibrary

  Alt 18. Jun 2011, 10:29
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
  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 17:28 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