Autor Beitrag
Uwe.F.
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 52

W7
D7 Ent. w/o NET
BeitragVerfasst: Sa 03.05.08 22:02 
Hallo Kollegen,

in Verbindung mit INI-Files gibt es zum Schreiben/Laden von Binärdaten das Funktionspärchen
ausblenden 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 user profile iconNarses: Delphi-Tags hinzugefügt
Moderiert von user profile iconNarses: Topic aus Sonstiges (Delphi) verschoben am Sa 03.05.2008 um 23:16
Narses
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Administrator
Beiträge: 10185
Erhaltene Danke: 1261

W11x64
TP3 .. D7pro .. D10.2CE
BeitragVerfasst: Sa 03.05.08 22:21 
Moin!

user profile iconUwe.F. hat folgendes geschrieben:
ein Binärfeld, für welches ich i.d.R. einen Pointer habe
In diesem Fall würde ich Suche in: Delphi-Forum, Delphi-Library BINTOHEX und Suche in: Delphi-Forum, Delphi-Library HEXTOBIN mit .WriteString() verwenden, sonst musst du die Daten zusätzlich auch noch in einem TStream-Nachfahren kapseln. :idea:

cu
Narses

_________________
There are 10 types of people - those who understand binary and those who don´t.
Uwe.F. Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 52

W7
D7 Ent. w/o NET
BeitragVerfasst: 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:
ausblenden 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 user profile iconNarses: Delphi-Tags hinzugefügt
Narses
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Administrator
Beiträge: 10185
Erhaltene Danke: 1261

W11x64
TP3 .. D7pro .. D10.2CE
BeitragVerfasst: So 04.05.08 21:52 
Moin!

user profile iconUwe.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... :!:

user profile iconUwe.F. hat folgendes geschrieben:
Beim Probieren bin ich über eine Variable vom Type "TObject" gestolpert:
ausblenden 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 :idea:) 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. Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 52

W7
D7 Ent. w/o NET
BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Administrator
Beiträge: 10185
Erhaltene Danke: 1261

W11x64
TP3 .. D7pro .. D10.2CE
BeitragVerfasst: So 04.05.08 22:19 
Moin!

user profile iconUwe.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. :nixweiss: Du musst anders an die Aufgabe rangehen. Ist vielleicht besser, du beschreibst mal, was das werden soll. ;)

user profile iconUwe.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? :zwinker:

user profile iconUwe.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. :idea:

cu
Narses

_________________
There are 10 types of people - those who understand binary and those who don´t.
Uwe.F. Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 52

W7
D7 Ent. w/o NET
BeitragVerfasst: 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? :zwinker:
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. :idea:
Das ist immer noch mein Ziel - trotz aller Widrigkeiten ;-)

In die Registry kommt mir jedenfalls nix!

Beste Grüße,
Uwe
Narses
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Administrator
Beiträge: 10185
Erhaltene Danke: 1261

W11x64
TP3 .. D7pro .. D10.2CE
BeitragVerfasst: So 04.05.08 23:06 
Moin!

user profile iconUwe.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... :roll: ("geht-doch"-Prinzip)

user profile iconUwe.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. :shock:

user profile iconUwe.F. hat folgendes geschrieben:
D.h.die INI bringt mir hier eh keine Vorteile.
Doch tut sie, wenn man ein brauchbares Konzept verwendet. ;)

user profile iconUwe.F. hat folgendes geschrieben:
Nur bekomme ich dann 99 Zeilen statt einer.
Und? :nixweiss:

user profile iconUwe.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. :idea:

cu
Narses

_________________
There are 10 types of people - those who understand binary and those who don´t.
j.klugmann
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Mo 05.05.08 08:50 
MOin,
könnte man nicht auch die WIN.INI benutzen:
ausblenden Delphi-Quelltext
1:
2:
s := 'c:\test\test' + #0;
WriteProfileString('Testabschnitt', 'Verzeichnis',@s[1]);
BenBE
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 8721
Erhaltene Danke: 191

Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
BeitragVerfasst: 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. Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 52

W7
D7 Ent. w/o NET
BeitragVerfasst: Sa 10.05.08 21:25 
Hallo Kollegen,

habe alles fertig und es geht auch alles :beer:

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:

ausblenden 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
    // Einlesen eines Arrays als Binärfeld:
    HexStrToBin(INIFile.ReadString('Section', 'Variable', ''), @Variable);
    // so kann man auch alle Werte, für die die INI nichts vorgesehen hat,
    // über HexStrToBin verarbeiten (z.B. mein o.a. TObject ;-) nämlich
    // die Info "Sender: TObject")
    ...


Umgekehrt gibt's die komplementäre Variante:

ausblenden 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
    // ein Array ...
    INIFile. WriteString('Tol', 'ToloHE', BinToHexStr( @ToloHE, SizeOf(ToloHE)));
    // eine Windows-Variable, die sich weder WriteInteger noch mit irgend 
    // etwas anderem speichern lässt:
    INIFile.WriteString('General', 'PrnOrient', BinToHexStr( @PrnOrient, SizeOf(PrnOrient)));


Vielleicht braucht es ja mal jemand.

Beste Grüße,
Uwe
Narses
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Administrator
Beiträge: 10185
Erhaltene Danke: 1261

W11x64
TP3 .. D7pro .. D10.2CE
BeitragVerfasst: So 11.05.08 22:58 
Moin!

user profile iconUwe.F. hat folgendes geschrieben:
habe alles fertig und es geht auch alles :beer:
[...]
Falls jemand mal so etwas sucht
...kann ich nur dringend davon abraten, das so umzusetzen! :shock: :mahn:

user profile iconUwe.F. hat folgendes geschrieben:
so habe ich es gemacht:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
Procedure LoadIni;
//...
begin 
  INIFile:=TMemIniFile.create(AppDataPath + INIFileName);
  try
    // Einlesen eines Arrays als Binärfeld:
    HexStrToBin(INIFile.ReadString('Section', 'Variable', ''), @Variable);
    // so kann man auch alle Werte, für die die INI nichts vorgesehen hat,
    // über HexStrToBin verarbeiten (z.B. mein o.a. TObject ;-) nämlich
    // die Info "Sender: TObject")
    ...
Abgesehen davon, dass es an programmtechnischen Selbstmord grenzt, sich in einer Konfig-Datei die Pointer-Offsets zu merken :nut:, hebelst du auf diesem Weg komplett den Sinn einer Tag-basierten Einstellungsdatei aus. :nixweiss:

Nochmal: ich rate jedem dringend, die Finger von sowas zu lassen! :hair:

cu
Narses

_________________
There are 10 types of people - those who understand binary and those who don´t.