| Autor |
Beitrag |
Uwe.F.
      
Beiträge: 52
W7
D7 Ent. w/o NET
|
Verfasst: Sa 03.05.08 22:02
Hallo Kollegen,
in Verbindung mit INI-Files gibt es zum Schreiben/Laden von Binärdaten das Funktionspärchen
Delphi-Quelltext 1: 2:
| function ReadBinaryStream(const Section, Name: string; Value: TStream): Integer; procedure WriteBinaryStream(const Section, Name: string; Value: TStream); |
Da ich mit den "Streams" überhaupt noch nicht gearbeitet habe, bräuchte ich mal einen kleinen Tip, wie ich ein Binärfeld, für welches ich i.d.R. einen Pointer habe, mit diesen Funktionen bearbeiten kann.
Hat jemand Lust, mir einen kleinen Tip zu geben?
Beste Grüße,
Uwe
Moderiert von Narses: Delphi-Tags hinzugefügtModeriert von Narses: Topic aus Sonstiges (Delphi) verschoben am Sa 03.05.2008 um 23:16
|
|
Narses
      

Beiträge: 10185
Erhaltene Danke: 1261
W11x64
TP3 .. D7pro .. D10.2CE
|
Verfasst: Sa 03.05.08 22:21
Moin!
Uwe.F. hat folgendes geschrieben: | | ein Binärfeld, für welches ich i.d.R. einen Pointer habe |
In diesem Fall würde ich BINTOHEX und HEXTOBIN mit .WriteString() verwenden, sonst musst du die Daten zusätzlich auch noch in einem TStream-Nachfahren kapseln.
cu
Narses
_________________ There are 10 types of people - those who understand binary and those who don´t.
|
|
Uwe.F. 
      
Beiträge: 52
W7
D7 Ent. w/o NET
|
Verfasst: So 04.05.08 16:28
Ja, das könnte auch gehen. Wie lang darf denn so ein String in der INI sein?
Beim Probieren bin ich über eine Variable vom Type "TObject" gestolpert:
Delphi-Quelltext 1: 2: 3: 4:
| FTastenbelegung = record T: shortstring; Z: TObject; end; |
Wie speichere ich denn das "TObject"?
Hat da jemand eine Idee?
Beste Grüße,
Uwe
Moderiert von Narses: Delphi-Tags hinzugefügt
|
|
Narses
      

Beiträge: 10185
Erhaltene Danke: 1261
W11x64
TP3 .. D7pro .. D10.2CE
|
Verfasst: So 04.05.08 21:52
Moin!
Uwe.F. hat folgendes geschrieben: | | Ja, das könnte auch gehen. Wie lang darf denn so ein String in der INI sein? |
Es gab da glaub ich eine Begrenzung für die Gesamtgröße einer INI-Datei.  Aber, INI-Files sind nicht als Datenlager gedacht, sondern dazu da, Programmoptionen zu speichern. Das ist also eh nix für größere Mengen Daten...
Uwe.F. hat folgendes geschrieben: | Beim Probieren bin ich über eine Variable vom Type "TObject" gestolpert:
Delphi-Quelltext 1: 2: 3: 4:
| FTastenbelegung = record T: shortstring; Z: TObject; end; |
Wie speichere ich denn das "TObject"? |
Nun, garnicht, vermutlich, jedenfalls nicht bei deinem Kenntnisstand von OOP...  (war nicht persönlich gemeint, ein OOP-Tutorial könnte dir aber sicher nicht schaden  ) Ganz kurz warum: TObject ist der Urahn aller Objekte und als solcher dient er als Platzhalter für alle seine Nachfahren. Ohne also zu wissen, um welches spezielle Objekt es sich handelt, wirst du das kaum allgemein handhaben können.
cu
Narses
_________________ There are 10 types of people - those who understand binary and those who don´t.
|
|
Uwe.F. 
      
Beiträge: 52
W7
D7 Ent. w/o NET
|
Verfasst: So 04.05.08 22:12
Hi!
Das TObject ist schon speiell: es ist die Variable "Sender" in OnKeyDown oder OnClick Routinen:
procedure TMainForm.MenuClick(Sender: TObject);
Diesen "Sender" will ich ich in der INI speichern um ihn später wiederverwenden zu können. Dürfte doch eigentlich nur ein Pointer sein, oder?
Mit der Frage nach der Stringlänge will ich nicht andeuten, dass ich die INI als Datenspeicher missbrauche. Nur habe ich beispielsweise ein Config-Array mit 99 Elementen abzuspeichern. Bevor ich aber 99 Einträge erzeuge, will ich das Ding als ein Binäfeld abspeichern.
Bisher hatte ich die ganze Configstruktur (um 24 kByte großes Record) als Binärfile abgespeichert. Hat nur leider den Nachteil, dass wenn ein Update mit geänderter Config kommt, der Nutzer alle individuellen Einstellungen erneut vornehmen muss.
Bei ner INI wird der nach Update in der alten Config fehlende Eintrag einfach auf den Defaultwert gesetzt und beim Programmende wird die erweiterte INI gespeichert. Damit bleiben alle Einstellungen erhalten.
Beste Grüße
Zuletzt bearbeitet von Uwe.F. am So 04.05.08 22:20, insgesamt 1-mal bearbeitet
|
|
Narses
      

Beiträge: 10185
Erhaltene Danke: 1261
W11x64
TP3 .. D7pro .. D10.2CE
|
Verfasst: So 04.05.08 22:19
Moin!
Uwe.F. hat folgendes geschrieben: | Das TObject ist die Variable "Sender" in einer OnKeyDown oder OnClick Routine:
procedure TMainForm.MenuClick(Sender: TObject);
Diesen "Sender" will ich ich in der INI speichern...
Dürfte doch eigentlich nur ein Pointer sein, oder? |
Das geht nicht so einfach, wie du dir das vorstellst...  Selbst wenn du "einfach nur den Pointer abspeicherst", was nutzt das? In der nächsten Programminstanz hat der Pointer doch keine Güligkeit mehr.  Du musst anders an die Aufgabe rangehen. Ist vielleicht besser, du beschreibst mal, was das werden soll.
Uwe.F. hat folgendes geschrieben: | | Nur habe ich beispielsweise ein Config-Array mit 99 Elementen abzuspeichern. Bevor ich aber 99 Einträge erzeuge, will ich das Ding als ein Binäfeld abspeichern. |
Wozu gibt es Schleifen?
Uwe.F. hat folgendes geschrieben: | | Bisher hatte ich die ganze Configstruktur (um 24 kByte großes Record) als Binärfile abgespeichert. Hat nur leider den Nachteil, dass wenn ein Update mit geänderter Config kommt, der Nutzer alle individuellen Einstellungen erneut vornehmen muss. |
Du hast es erkannt, Binärdateien als Config-Files sind keine gute Idee.
Und deshalb rate ich dir dringend dazu, die ganzen Einstellungen als INI anzulegen.
cu
Narses
_________________ There are 10 types of people - those who understand binary and those who don´t.
|
|
Uwe.F. 
      
Beiträge: 52
W7
D7 Ent. w/o NET
|
Verfasst: So 04.05.08 22:32
Hallo Narses,
das Abspeichern der Sender-Variable und der anschließenden Benutzung geht einwandfrei.
Wenn ich das mit der INI nicht hinbekomme, belasse ich es hier bei der alten Form (Abspeichern der Struktur im Binärformat).
Nach Neukompilierung und/oder Neuinstallation geht das eh nicht mehr; dann greift das was Du schriebst: die Pointer sind ungültig.
D.h.die INI bringt mir hier eh keine Vorteile.
| Zitat: | Wozu gibt es Schleifen?  |
Ja, das wäre das einfachste. Nur bekomme ich dann 99 Zeilen statt einer. Wie ich verstanden habe, wird bei jedem Zugriff die gesamte INI durchsucht. Also denke ich mir, ein Zugriff für das ganze Array ist besser als 99 Zugriffe (und vor allem kleiner).
| Zitat: | Du hast es erkannt, Binärdateien als Config-Files sind keine gute Idee.
Und deshalb rate ich dir dringend dazu, die ganzen Einstellungen als INI anzulegen.  |
Das ist immer noch mein Ziel - trotz aller Widrigkeiten
In die Registry kommt mir jedenfalls nix!
Beste Grüße,
Uwe
|
|
Narses
      

Beiträge: 10185
Erhaltene Danke: 1261
W11x64
TP3 .. D7pro .. D10.2CE
|
Verfasst: So 04.05.08 23:06
Moin!
Uwe.F. hat folgendes geschrieben: | | das Abspeichern der Sender-Variable und der anschließenden Benutzung geht einwandfrei. |
Wenn du davon überzeugt bist, das du alles im Griff hast, dann mach mal weiter so. Empirische Informatik...  ("geht-doch"-Prinzip)
Uwe.F. hat folgendes geschrieben: | | Nach Neukompilierung und/oder Neuinstallation geht das eh nicht mehr; dann greift das was Du schriebst: die Pointer sind ungültig. |
Und genau deshalb ist das eine ziemlich üble Fehlerquelle, die man vermeiden sollte.
Uwe.F. hat folgendes geschrieben: | | D.h.die INI bringt mir hier eh keine Vorteile. |
Doch tut sie, wenn man ein brauchbares Konzept verwendet.
Uwe.F. hat folgendes geschrieben: | | Nur bekomme ich dann 99 Zeilen statt einer. |
Und?
Uwe.F. hat folgendes geschrieben: | | Wie ich verstanden habe, wird bei jedem Zugriff die gesamte INI durchsucht. Also denke ich mir, ein Zugriff für das ganze Array ist besser als 99 Zugriffe (und vor allem kleiner). |
Dann nimm eben TMemIniFile.
cu
Narses
_________________ There are 10 types of people - those who understand binary and those who don´t.
|
|
j.klugmann
Ehemaliges Mitglied
Erhaltene Danke: 1
|
Verfasst: Mo 05.05.08 08:50
MOin,
könnte man nicht auch die WIN.INI benutzen:
Delphi-Quelltext 1: 2:
| s := 'c:\test\test' + #0; WriteProfileString('Testabschnitt', 'Verzeichnis',@s[1]); |
|
|
BenBE
      
Beiträge: 8721
Erhaltene Danke: 191
Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
|
Verfasst: Di 06.05.08 09:49
Sorry, aber das ist Schwachsinn:
1. Die Windows-API ist nicht die performanteste Variante
2. Im Windows-Verzeichnis dürfen nur Admins schreiben
3. Große Datenmengen gehören nicht in INI-Dateien ...
Schau Dir da lieber TFastIniFile an, oder nach Wunsch auch TBigIniFIle\TAppIniFile ... Die sind für große Datenmengen optimiert ...
_________________ Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.
|
|
Uwe.F. 
      
Beiträge: 52
W7
D7 Ent. w/o NET
|
Verfasst: Sa 10.05.08 21:25
Hallo Kollegen,
habe alles fertig und es geht auch alles
Die neue INI ist mit allen Daten (einschließlich der Binärdaten) rnd. 24 kByte groß, und wird über TMemIniFile in einer Millisekunde eingelesen.
Falls jemand mal so etwas sucht, so habe ich es gemacht:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17:
| Procedure LoadIni; var INIFile : TMemIniFile; Procedure HexStrToBin(const Str: String; P: Pointer); var len: integer; begin HexToBin( PChar(Str), P, Len); end;
begin INIFile:=TMemIniFile.create(AppDataPath + INIFileName); try HexStrToBin(INIFile.ReadString('Section', 'Variable', ''), @Variable); ... |
Umgekehrt gibt's die komplementäre Variante:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16:
| Procedure StoreINI; var INIFile : TMemIniFile; function BinToHexStr(P: PChar; Len: Integer): String; var str: string; begin SetString(Result, nil, Len * 2); BinToHex(P, PChar(Result), Len); end; begin INIFile:=TMemIniFile.create(AppDataPath + INIFileName); try INIFile. WriteString('Tol', 'ToloHE', BinToHexStr( @ToloHE, SizeOf(ToloHE))); INIFile.WriteString('General', 'PrnOrient', BinToHexStr( @PrnOrient, SizeOf(PrnOrient))); |
Vielleicht braucht es ja mal jemand.
Beste Grüße,
Uwe
|
|
Narses
      

Beiträge: 10185
Erhaltene Danke: 1261
W11x64
TP3 .. D7pro .. D10.2CE
|
Verfasst: So 11.05.08 22:58
Moin!
Uwe.F. hat folgendes geschrieben: | habe alles fertig und es geht auch alles
[...]
Falls jemand mal so etwas sucht |
...kann ich nur dringend davon abraten, das so umzusetzen!
Uwe.F. hat folgendes geschrieben: | so habe ich es gemacht:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11:
| Procedure LoadIni; begin INIFile:=TMemIniFile.create(AppDataPath + INIFileName); try HexStrToBin(INIFile.ReadString('Section', 'Variable', ''), @Variable); ... | |
Abgesehen davon, dass es an programmtechnischen Selbstmord grenzt, sich in einer Konfig-Datei die Pointer-Offsets zu merken  , hebelst du auf diesem Weg komplett den Sinn einer Tag-basierten Einstellungsdatei aus.
Nochmal: ich rate jedem dringend, die Finger von sowas zu lassen!
cu
Narses
_________________ There are 10 types of people - those who understand binary and those who don´t.
|
|
|