![]() |
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:
Falls ihr irgendwelche fragen habt oder ihr mehr information braucht sagt bitte bescheid !
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. Zurzeit benutze ich die Indy Komponente für delphi (version xe7) Danke für eure Antworten :) |
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. |
AW: Hilfe mit Delphi [idhttp.get error]
Zitat:
![]() 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:
|
AW: Hilfe mit Delphi [idhttp.get error]
Zitat:
|
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:
Jetzt rate mal wie die Datei heißt und wo sie liegt? :roll:
edit1.Text := (dir);
... ... ... ResponseStream := TFileStream.Create(Edit1.Text, fmCreate); Ausgewählte Verzeichnis: c:\ddd\eee -> Dateiname eee im Verzeichnis c:\ddd. Ich glaube kaum, dass das funktionieren wird. |
AW: Hilfe mit Delphi [idhttp.get error]
Zitat:
Zitat:
Zitat:
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 ![]() Zitat:
Delphi-Quellcode:
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?
idHTTP1.Get(url, ResponseStream);
AResponseContent is the TStream instance that is the destination for data retrieved from the specified URL. For example: AHttp.Get(AUrl, AResponseContent) |
AW: Hilfe mit Delphi [idhttp.get error]
Ok, überlesen. Aber letztendlcih wird es daran scheitern dass ein Verzeichnis übergeben wird und kein Dateiname.
|
AW: Hilfe mit Delphi [idhttp.get error]
Noch besser, das "dir" ist erstmal ein "path", denn
Delphi-Quellcode:
, aber hier passt Vieles nicht so ganz.
dir := ExtractFilePath(Application.ExeName);
PS: @BlobFeldInDatei
Delphi-Quellcode:
ist etwas sinnlos nutzlos, denn es muß zwangsläufig immer True zurückgeben.
Result := FileExists(Datei);
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. |
AW: Hilfe mit Delphi [idhttp.get error]
Zitat:
Du meinst, das
Delphi-Quellcode:
gehört in den Try-Finally-Block? Klingt logisch, werde ich gleich mal ändern. Dann macht auch
TFileStream.Create
Delphi-Quellcode:
Sinn, obwohl ich da natürlich genausogut schreiben könnte
Result := FileExists(Datei);
Delphi-Quellcode:
.
Result := True;
Du hast meinen Code verbessert, dafür sei dir mein Dank gewiß :cheers: |
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: |
AW: Hilfe mit Delphi [idhttp.get error]
Generell sollte man sowas etwas mehr trennen:
Delphi-Quellcode:
Schon wird es kürzer und knackiger, obwohl es jetzt zwei Methoden sind ;)
procedure TDatMod.DoStoreBlobToFile(Feld: TField; Datei: String);
Var S : TStream; FileS : TFileStream; begin If Not Feld.IsBlob Then raise Exception.Create( 'Das angegebene Feld ist kein Blobfeld.' ); If Feld.IsNull Then raise Exception.Create( 'Im angegebenen Blobfeld des aktuellen Records befinden sich keine Daten.' ); S := nil; FileS := nil; Try S := Feld.DataSet.CreateBlobStream(Feld, bmRead); FileS := TFileStream.Create(Datei, fmCreate); FileS.CopyFrom(S, S.Size ); Finally S.Free; FileS.Free; End; if not FileExists( Datei ) then raise Exception.CreateFmt( 'Eigentlich sollte die Datei "%s" jetzt vorhanden sein?', [Datei] ); end; Function TDatMod.BlobFeldInDatei(Feld: TField; Datei: String): Boolean; begin Result := True; try DoStoreBlobToFile( Feld, Datei ); except on E: Exception do begin GLD.FehlerText := E.Message; Result := False; end; end; end; |
AW: Hilfe mit Delphi [idhttp.get error]
Zitat:
Delphi-Quellcode:
Und wird eine Objektvariable nicht automatisch bei der Deklaration mit Nil initialisiert? Oder muß ich das dann auch bereits vor dem ersten Try machen?
procedure TObject.Free;
begin // under ARC, this method isn't actually called since the compiler translates // the call to be a mere nil assignment to the instance variable, which then calls _InstClear {$IFNDEF AUTOREFCOUNT} if Self <> nil then Destroy; {$ENDIF} end; So dürfte es dann wohl hinhauen:
Delphi-Quellcode:
Function TDatMod.BlobFeldInDatei(Feld: TField; Datei: String): Boolean;
Var S : TStream; FileS : TFileStream; begin Result := False; ... Try S := Feld.DataSet.CreateBlobStream(Feld, bmRead); FileS := TFileStream.Create(Datei, fmCreate); Try FileS.CopyFrom(S, S.Size); Result := True; Except on e:exception Do GLD.FehlerText := 'Fehler bei BlobToFile: ' + e.Message; End; Finally S.Free; FileS.Free; End; end; |
AW: Hilfe mit Delphi [idhttp.get error]
Ja, Free prüft auf nil, aber lokale Variablen sind nicht unbedingt automatisch mit nil initialisiert. :zwinker:
Aber das sollte dir der Compiler auch sagen. :stupid: Entweder es knallt nicht, weil der Zeiger zufällig auf "irgendein" Objekt zeigt und es dann freigegeben wird, oder es knallt hoffentlich. :angle2: |
AW: Hilfe mit Delphi [idhttp.get error]
Jetzt ist der Groschen auch bei mir gefallen:
UnitData.pas(331,1): warning W1036: W1036 Variable 'S' ist möglicherweise nicht initialisiert worden UnitData.pas(331,1): warning W1036: W1036 Variable 'FileS' ist möglicherweise nicht initialisiert worden Okay, dann füge ich die Nilsetzung vor dem ersten Try ein und gut ist :thumb: Zitat:
Jetzt ist ja alles wieder gut :-D |
AW: Hilfe mit Delphi [idhttp.get error]
Zitat:
Delphi-Quellcode:
scheitert geht er nach except und danach nach finaly. Dort veursacht FileS.Free ebenfalls eine Exception falls nicht zufällig mit nil initiiert. Deshalb hat Sir Rufo FileS erst mal nil gesetzt. Alternativ kann man auch 2 try finally Blöcke nehmen.
S := Feld.DataSet.CreateBlobStream(Feld, bmRead);
|
AW: Hilfe mit Delphi [idhttp.get error]
Mehrere Frees in einem Finaly geht natürlich nur, wenn alle Frees selber keine Exceptions erzeugen können (also jeweils die Free vor einem anderen Free ... sozusagen der Letzte darf knallen, wenn er will)
Wenn das nicht nahezu sichergestellt ist, dann entweder jeder sein eigenes Try-Finally, oder ein Try-Finally/Except im Finally. Fälle, wonach das Programm dann eh komplett im Arsch ist und sowieso beendet werden muß, "kann" man weniger sorgsam sichern. |
AW: Hilfe mit Delphi [idhttp.get error]
Zitat:
Delphi-Quellcode:
Block zu nehmen, denn dann sieht man irgendwann den Wald vor lauter Bäumen (
try finally
Delphi-Quellcode:
und Einrückungen) nicht mehr :mrgreen:
try
Und schreibfaul bin ich auch noch ;) |
AW: Hilfe mit Delphi [idhttp.get error]
Hallo Leute !
Erstmal danke für eure zahlreichen Antwroten ! :) Ich werde mir die gelisteten Tipps von himitsu raussuchen und so gut wie es geht beheben ! Jedoch habe ich als Anfänger gerade einmal die hälfte Verstanden :? Ich werde im Verlaufe des Tages Updates posten :) @himitsu : Sie meinten das dir kein path sein soll ? Was soll den Dir sonst sein ? versteh ich nicht ganz :? Und das mit dem TOpenDialog habe auch nach dem Lesen im Wiki nicht verstanden :? Gruß RooT |
AW: Hilfe mit Delphi [idhttp.get error]
Himitsu meinte, daß du für das Abspeichern des des TFileStreams eine Datei und nicht nur ein Verzeichnis benötigst:
Nicht C:\MeinOrdner\ sondern C:\MeinOrdner\Datei.html |
AW: Hilfe mit Delphi [idhttp.get error]
Path: C:\Programme\ = etwas in dem Verzeichnis (Pfadangabe für eine Datei/Verzeichnis zum Anhängen, also mit abschließendem PathDelimiter)
Directory, bzw. Pathname: C:\Programme = das Verzeichnis selber (der Verzeichnisname, also ohne abschließenden PathDelimiter) Filepath: C:\Programme\Meine.exe = eine bestimmte Datei (inkl. Pfad) Filename: Meine.exe = irgendeine Datei (ohne Pfad) SaveToFile benötigt einen FileName, aber idealer Weise besser einen kompletten FilePath Du schreibst aber erstmal einem Path in die Variable und der Auswahldialog wählt dann nur ein Verzeichnis (Dir). PS: '\', oder ![]() ![]() ![]() |
AW: Hilfe mit Delphi [idhttp.get error]
Zitat:
hier der neue code falls ihn vllt irgendwer mal braucht :)
Code:
Nurnoch eine letzte frage :) : Bei der gedownloadeten HTML Datei werden Bilder nicht angezeigt :? Gründe dafür und kann man das beheben ? :)
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; SpeicherEd: TEdit; SaveDialog1: TSaveDialog; AuswahlB: TButton; NameEd: TEdit; OpenDialog1: TOpenDialog; procedure Button1Click(Sender: TObject); procedure NameEdEnter(Sender: TObject); procedure AuswahlBClick(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(SpeicherEd.Text, fmCreate); try idHTTP1.Get(url, ResponseStream); finally ResponseStream.Free; end; ShowMessage('Download abgeschlossen'); end; procedure TForm3.AuswahlBClick(Sender: TObject); var dir : String; begin dir := ExtractFilePath(Application.ExeName); if SelectDirectory ('Bitte ein Verzeichnis auswählen','',Dir) then SpeicherEd.Text := (dir+'\'+NameEd.text+'.html'); end; procedure TForm3.NameEdEnter(Sender: TObject); begin NameEd.Text := ''; end; end. Gruß |
AW: Hilfe mit Delphi [idhttp.get error]
In der Regel ist das ja so, dass die Bilder kein Teil der HTML-Datei sind. Stattdessen steht in der HTML-Datei ja eine URL oder so des Bildes in einem Image-Tag, was dem Browser sagt, dass er das Bild nachladen und anzeigen soll.
|
AW: Hilfe mit Delphi [idhttp.get error]
Zitat:
Oder vllt mit einem anderen Code Komponente ? Gruß RooT |
AW: Hilfe mit Delphi [idhttp.get error]
Zitat:
|
AW: Hilfe mit Delphi [idhttp.get error]
Zitat:
Korrigiert mich bitte falls ich falsch liege :) Gruß RooT |
AW: Hilfe mit Delphi [idhttp.get error]
Zitat:
- Die <img>-Tags in der HTML-Datei entsprechend anpassen (wie du geschrieben hast) - die gleiche Verzeichnisstruktur wie auf dem Server verwenden (nur möglich wenn die Site ausschließlich relative Pfadangaben nutzt) - ![]() |
AW: Hilfe mit Delphi [idhttp.get error]
Zitat:
Gruß RooT |
AW: Hilfe mit Delphi [idhttp.get error]
Beispielcode habe ich leider keinen. Im Prinzip musst du die HTML-Datei nach <img> Tags durchsuchen, darin findest du z.B. ein "src=EinBild.jpg"; dieses musst du dann ebenfalls downloaden und ggf. das "src=..." in der HTML-Datei entsprechend anpassen.
Was willst du eigentlich erreichen? Du schreibst oben etwas von "nach PDF konvertieren", da gibt es aber auch schon fertige Onlinedienste... |
AW: Hilfe mit Delphi [idhttp.get error]
Zitat:
Möchte die Datei später mit einer selbst programmierten App auf ein Smartphone übertragen :) Und da PDF Dateien so gut wie auf jedem Smartphone dargestellt werden können habe ich mich für dieses Format entschieden zudem ist es oftmals leichter zu lesen etc. :) Gruß RooT |
AW: Hilfe mit Delphi [idhttp.get error]
Zitat:
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 00:06 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