Delphi-PRAXiS
Seite 1 von 3  1 23      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Algorithmen, Datenstrukturen und Klassendesign (https://www.delphipraxis.net/78-algorithmen-datenstrukturen-und-klassendesign/)
-   -   Hilfe mit Delphi [idhttp.get error] (https://www.delphipraxis.net/184509-hilfe-mit-delphi-%5Bidhttp-get-error%5D.html)

RooT314 31. Mär 2015 22:30

Hilfe mit Delphi [idhttp.get error]
 
Hey Leute !

Ich beschäftige mich seit einigen tagen mit einem neuen Projekt und als anfänger habe ich noch nicht wirklich sehr viel erfahrung und habe deswegen ein paar fragen die ihr mir hoffentlich beantworten könnt !

Mein Programm : Ich möchte eine Wikipedia seite aufrufen (zzt. passiert dies über den Standardbrowser) und daraufhin wird eine neue unit geöffnet die fragt ob dies der richtige Artikel ist den jemand speichern möchte falls der benutzer ja klickt soll die html datei als pdf gespeichert werden

So hier ist mein code mit dem ich leider nicht viel weiter komme, da mir das Programm nicht erlaubt die Datei irgendwo zu speichern (egal welcher Speicherort & auch nicht als Admin)

Code vom JA Knopf aus der Unit3
Code:
unit Unit3;

interface

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

type
  TForm3 = class(TForm)
    Label1: TLabel;
    Button1: TButton;
    Button2: TButton;
    IdHTTP1: TIdHTTP;
    Edit1: TEdit;
    SaveDialog1: TSaveDialog;
    Button3: TButton;
    Edit2: TEdit;
    procedure Button1Click(Sender: TObject);
    procedure Edit2Enter(Sender: TObject);
    procedure Button3Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Speicherort, Form3: TForm3;

implementation

uses
  unit2, unit1, Filectrl;
{$R *.dfm}

procedure TForm3.Button1Click(Sender: TObject);
var ResponseStream: TFileStream;
begin
  ResponseStream := TFileStream.Create(Edit1.Text, fmCreate);
  try
    idHTTP1.Get(url, ResponseStream);
  finally
    ResponseStream.Free;
    end;
    ShowMessage('Download abgeschlossen');
  end;

procedure TForm3.Button3Click(Sender: TObject);
var dir : String;
begin
  dir := ExtractFilePath(Application.ExeName);
  if SelectDirectory ('Bitte ein Verzeichnis auswählen','',Dir)
    then
    edit1.Text := (dir);

end;

procedure TForm3.Edit2Enter(Sender: TObject);
begin
 Edit2.Text := '';
end;

end.
Falls ihr irgendwelche fragen habt oder ihr mehr information braucht sagt bitte bescheid !

Zurzeit benutze ich die Indy Komponente für delphi (version xe7)

Danke für eure Antworten :)

bcvs 1. Apr 2015 07:25

AW: Hilfe mit Delphi [idhttp.get error]
 
Ich sehe nicht, wo da irgendetwas gespeichert wird. Du liest den Inhalt einer Webseite in einen Stream und gibst den gleich wieder frei. Dazwischen müsste der Stream seinen Inhalt aber erstmal noch speichern (s. Write oder WriteBuffer).

Außerdem gibst du dem Stream beim create lediglich ein Verzeichnis an und keinen vollständigen Dateinamen.

Perlsau 1. Apr 2015 07:38

AW: Hilfe mit Delphi [idhttp.get error]
 
Zitat:

Zitat von bcvs (Beitrag 1295678)
Ich sehe nicht, wo da irgendetwas gespeichert wird. Du liest den Inhalt einer Webseite in einen Stream und gibst den gleich wieder frei. Dazwischen müsste der Stream seinen Inhalt aber erstmal noch speichern (s. Write oder WriteBuffer).

Lies doch erstmal den Text der Online-Hilfe zu TFileStream.Create, bevor du da was behauptest:
fmCreate – Erstellt eine Datei mit dem angegebenen Namen. Ist eine Datei mit diesem Namen bereits vorhanden, wird die Datei zum Schreiben geöffnet.
Das heißt: In dem Moment, in dem du in einen geöffneten Filestream was reinschreibst, wird das auf Platte geschrieben. Ich mach das seit Jahr und Tag mit meiner Blob-To-File-Funktion ganz genau so:
Delphi-Quellcode:
Function TDatMod.BlobFeldInDatei(Feld: TField; Datei: String): Boolean;
Var
  S    : TStream;
  FileS : TFileStream;

begin
  Result := False;

  If Not Feld.IsBlob Then
  Begin
    GLD.Fehlertext := 'Das angegebene Feld ist kein Blobfeld.';
    Exit;
  End;

  If Feld.IsNull Then
  Begin
    GLD.Fehlertext := 'Im angegebenen Blobfeld des aktuellen Records befinden sich keine Daten.';
    Exit;
  End;

  S    := Feld.DataSet.CreateBlobStream(Feld, bmRead);
  FileS := TFileStream.Create(Datei, fmCreate);

  Try
    Try
      FileS.CopyFrom(S, S.Size);
      Result := FileExists(Datei);
    Except
      on e:exception Do
      Begin
        GLD.FehlerText := 'Fehler bei BlobToFile: ' + e.Message;
        Result := False;
      End;
    End;
  Finally
    S.Free;
    FileS.Free;
  End;
end;
Zitat:

Zitat von bcvs (Beitrag 1295678)
Außerdem gibst du dem Stream beim create lediglich ein Verzeichnis an und keinen vollständigen Dateinamen.

Das dürfte wohl eher die Fehlerursache sein ...

bcvs 1. Apr 2015 07:58

AW: Hilfe mit Delphi [idhttp.get error]
 
Zitat:

Zitat von Perlsau (Beitrag 1295685)
fmCreate – Erstellt eine Datei mit dem angegebenen Namen. Ist eine Datei mit diesem Namen bereits vorhanden, wird die Datei zum Schreiben geöffnet.
Das heißt: In dem Moment, in dem du in einen geöffneten Filestream was reinschreibst, wird das auf Platte geschrieben.

OK, dass das so funktioniert, wusste ich nicht, gebe ich zu. Aber aus der Hilfe lese ich das auch nicht. Da steht nur, dass die Datei zum Schreiben geöffnet wird, und nicht das da auch automatisch was reingeschreiben wird, wenn man in den Stream was reinschreibt.

Luckie 1. Apr 2015 08:25

AW: Hilfe mit Delphi [idhttp.get error]
 
@Perlsau: Nur im Unterschied zum Threadersteller schreibst du auch was rein
Delphi-Quellcode:
FileS.CopyFrom(S, S.Size);
Delphi-Quellcode:
 edit1.Text := (dir);
...
...
...
ResponseStream := TFileStream.Create(Edit1.Text, fmCreate);
Jetzt rate mal wie die Datei heißt und wo sie liegt? :roll:

Ausgewählte Verzeichnis: c:\ddd\eee -> Dateiname eee im Verzeichnis c:\ddd. Ich glaube kaum, dass das funktionieren wird.

Perlsau 1. Apr 2015 08:32

AW: Hilfe mit Delphi [idhttp.get error]
 
Zitat:

Zitat von bcvs (Beitrag 1295689)
OK, dass das so funktioniert, wusste ich nicht, gebe ich zu.

Tja, man lernt nie aus, das gilt für mich ebenso :thumb:

Zitat:

Zitat von bcvs (Beitrag 1295689)
Aber aus der Hilfe lese ich das auch nicht.

Und wo hast du das mit dem WriteBuffer gelesen? Etwa in der Online-Hilfe zu TFileStream?

Zitat:

Zitat von bcvs (Beitrag 1295689)
Da steht nur, dass die Datei zum Schreiben geöffnet wird, und nicht das da auch automatisch was reingeschreiben wird, wenn man in den Stream was reinschreibt.

Zum Schreiben geöffnet heißt, sie wird erstellt und wartet darauf, daß geschrieben wird. Wie befüllt man ein geöffnetes Gefäß? Indem man was reingießt? Und wie schreibt man in einen Filestream? Indem man was reinkopiert? Also für mich ist der Text in der OH eindeutig.

Man sollte hier wirklich nichts behaupten, das man nicht zuvor überprüft hat, nur um sich hervorzutun mit einem "ich weiß auch was" und sich dann doch zu blamieren :cyclops:

Übrigens kann man im Codebeispiel zu TFileStream.Create genau diese Vorgehensweise finden.

Zitat:

Zitat von Luckie (Beitrag 1295693)
@Perlsau: Nur im Unterschied zum Threadersteller schreibst du auch was rein
Delphi-Quellcode:
FileS.CopyFrom(S, S.Size);

Und macht das der TE mit
Delphi-Quellcode:
idHTTP1.Get(url, ResponseStream);
etwa nicht? Was macht die Get-Version mit String als Var-Parameter? Richtig, das Resultat wird im String gespeichert. Warum sollte es bei einem Stream als Ziel-Behälter dann anders sein?

AResponseContent is the TStream instance that is the destination for data retrieved from the specified URL. For example: AHttp.Get(AUrl, AResponseContent)

Luckie 1. Apr 2015 08:39

AW: Hilfe mit Delphi [idhttp.get error]
 
Ok, überlesen. Aber letztendlcih wird es daran scheitern dass ein Verzeichnis übergeben wird und kein Dateiname.

himitsu 1. Apr 2015 09:04

AW: Hilfe mit Delphi [idhttp.get error]
 
Noch besser, das "dir" ist erstmal ein "path", denn
Delphi-Quellcode:
dir := ExtractFilePath(Application.ExeName);
, aber hier passt Vieles nicht so ganz.
  • erst wird in "dir" ein Pfad "path" reingeschrieben ( C:\dir\ )
  • dann noch der falsche Dialogtext "Bitte ein Verzeichnis auswählen" > Ergibt ein "dir" ( C:\dir\dir2 ), aber nur wenn man den Editinhalt ändert und nicht so belässt
  • Bezogen auf SelectDirectory stimmt der Text zwar, aber in "dir" Edit1 (echt blöde Name) soll doch ein Dateiname (samt path) rein ... warum dann kein TOpenDialog?
  • und zum Schluß wird das Verzeichnis "dir" auch noch direkt als Dateiname "file" verwendet ( C:\dir\file )
  • wenn wirklich ein Vereichnis (dir oder path) in "dir" und Edit1 rein soll, dann muß das eben bei TFileStream um den Dateinamen ergänzt werden




PS: @BlobFeldInDatei
Delphi-Quellcode:
Result := FileExists(Datei);
ist etwas sinnlos nutzlos, denn es muß zwangsläufig immer True zurückgeben.
Entweder knallte das TFileStream.Create und der Code kommt dort nie vorbei, oder TFileStream.Create(fmCreate) war erfolgreich und die Datei ist somit auch vorhanden.

Wenn TFileStream.Create knallt, dann bleibt auch noch der Blob-Stream schön als Speicherleck zurück.

Perlsau 1. Apr 2015 09:35

AW: Hilfe mit Delphi [idhttp.get error]
 
Zitat:

Zitat von himitsu (Beitrag 1295704)
PS: @BlobFeldInDatei
Delphi-Quellcode:
Result := FileExists(Datei);
ist etwas sinnlos nutzlos, denn es muß zwangsläufig immer True zurückgeben.
Entweder knallte das TFileStream.Create und der Code kommt dort nie vorbei, oder TFileStream.Create(fmCreate) war erfolgreich und die Datei ist somit auch vorhanden.
Wenn TFileStream.Create knallt, dann bleibt auch noch der Blob-Stream schön als Speicherleck zurück.

:wiejetzt:

Du meinst, das
Delphi-Quellcode:
TFileStream.Create
gehört in den Try-Finally-Block? Klingt logisch, werde ich gleich mal ändern. Dann macht auch
Delphi-Quellcode:
Result := FileExists(Datei);
Sinn, obwohl ich da natürlich genausogut schreiben könnte
Delphi-Quellcode:
Result := True;
.
Du hast meinen Code verbessert, dafür sei dir mein Dank gewiß :cheers:

himitsu 1. Apr 2015 09:43

AW: Hilfe mit Delphi [idhttp.get error]
 
Jupp, aber dann vor dem Try natürlich nicht das :=nil vergessen, denn sonst knallt auch noch das Free, da nicht initialisiert, wenn es im Create knallte.
2x Try-Finally, oder Create drinnen und davor initialisieren.

Sinn: Nja, wenn es im Create knallt, kommt es dennoch nicht beim Exists vorbei, außer Exists steckt im finally. :zwinker:


Alle Zeitangaben in WEZ +1. Es ist jetzt 17:30 Uhr.
Seite 1 von 3  1 23      

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