dYnAm1c - Mi 27.04.11 00:04
Titel: Indy HTTP *.Ini Abfrage
Hi,
bin gerade auf das Forum hier gestoßen und suche Hilfe für meinen kleinen "Update" -Code, welcher mit einer Ini Datei arbeitet welche sich auf einem Server befindet.
Das Tool soll lädt die "config.ini" vom Server runterladen, danach fängt allerdings der Fehler an. Ich möchte das die Version die in der Ini Datei steht ausgelesen wird und in "Listbox2.Items" geschrieben wird, allerdings scheint er diesen Schritt zu überspringen und sagt einfach sofort das die Version "up2date" ist. Der Code ist leider nicht sehr aufgeräumt, ist eins meiner etwas größeren Projekte ;). Hier die nötige Source:
Update Button:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30:
| procedure TForm2.UpdateBtnClick(Sender: TObject); var stream: TFileStream; ini: TiniFile; Version: Extended; begin if (rdy = 0) then begin stream := TFileStream.Create('config.ini', fmCreate); HTTP1.Get('http://raidtest.ra.funpic.de/config.ini', stream); end;
if (rdy = 1) then begin ini := TiniFile.Create(ExtractFilePath(ParamStr(0))+ 'config.ini'); ini.ReadSectionValues('VersionCL', Listbox2.Items); ini.Free; end; if (Listbox1.ItemIndex = Listbox2.ItemIndex) then begin Application.MessageBox('Your Client is already up 2 date!', 'Up 2 Date', MB_ICONINFORMATION or MB_OK); Exit; end else if (Listbox1.ItemIndex <> Listbox2.ItemIndex) then begin stream := TFileStream.Create('Chat Client 1.5.exe', fmCreate); HTTP2.Get('http://raidtest.ra.funpic.de/Chat_Client_1.5.exe'); end; end; |
Die WorkEnd Prozedur vom Ini Download:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7:
| procedure TForm2.HTTP1WorkEnd(ASender: TObject; AWorkMode: TWorkMode); begin Application.MessageBox('Config File Downloaded!', 'Config Download', MB_ICONINFORMATION or MB_OK); Stream.Free; rdy := 1; UpdateBtn.Click; end; |
Thom - Mi 27.04.11 15:01
Delphi-Quelltext
1: 2:
| Stream.Seek(0,soFromBeginning); |
Jeder Stream hat einen "Zeiger" auf die aktuelle Position innerhalb der Daten:
TStream.Position. Nach dem Schreiben in einen Stream beinhaltet
TStream.Position meist den Wert von
TStream.Size: Der "Zeiger" zeigt also auf das Ende des Streams.
Wird aus einem Stream gelesen, verwenden viele Komponenten den Wert aus
TStream.Position und fangen an, ab dieser Position ihre Daten zu lesen.
Im Falle von
TStringList.LoadFromStream würden also die "letzten" null Bytes geladen. Das wäre nicht so gut... Deshalb muß die Eigenschaft
TStream.Position auf Null - also den Anfang des Streams - gesetzt werden. Dazu bietet sich die Methode
TStream.Seek(Offset,Startpunkt) an. Bei
TStream.Seek(0,soFromBeginning) wird also das erste Byte vom Anfang des Streams aus "angesteuert". Den selben Effekt hättest Du natürlich auch mit
TStream.Position:=0.
Delphi-Quelltext
1: 2:
| OldDecimalSeparator := DecimalSeparator; DecimalSeparator:='.'; |
In Delphi und im englischsprachigen Raum ist das Dezimal-Trennzeichen kein Komma, sondern ein Punkt. Wird jetzt ein String in eine Fließkommazahl umgewandelt, wird das im jeweiligen PC eingestellt Gebietsschema genutzt: Bei einer Fließkommazahl wird das also in der Regel ein Komma sein. Damit kann der String nicht richtig umgewandelt werden und es kommt bei
StrToFloat() zu einer Exception.
Um das Ganze trotzdem hinzubekommen, kann über die globale Variable
DecimalSeparator bzw. in neueren Delphi-Versionen
FormatSettings.DecimalSeparator das Zeichen ausgewählt werden, das als Dezimal-Trennzeichen benutzt werden soll. Sehr zu empfehlen ist natürlich, den alten Wert zwischenzuspeichern und anschließend wieder herzustellen.
Delphi-Quelltext
1: 2:
| Version:=StrToFloatDef(Ini.Values['VersionCL'],0); |
StrToFloatDef erzeugt keine Exception, falls die Umwandlung eines Strings in eine Fließkommazahl nicht funktioniert, sondern nimmt im Fehlerfall einfach den übergebenen Wert. Ich kann allerdings nicht genau sagen, ab welcher Delphi-Version diese Funktion existiert.
TMemoryStream ist ein Stream, der nur im Speicher existiert,
TFileStream arbeitet mit einer Datei auf der Festplatte.
Mit
TIdHTTP.Get(URL,Stream) werden die empfangenen Daten im Stream gespeichert (in meinem Beispiel mit TMemoryStream nur im Hauptspeicher) und anschließend mit
TMemoryStream.SaveToFile in eine Datei geschrieben. Das könnte man natürlich auch mit
TFileStream realisieren. Ich wollte nur den Stream für die Versionsinformation für die eigentliche Datei wiederverwenden.