Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   FileStream mit "TIniFile Funktionalität".Methoden (https://www.delphipraxis.net/180520-filestream-mit-tinifile-funktionalitaet-methoden.html)

Bjoerk 26. Mai 2014 13:13

Delphi-Version: 2007

FileStream mit "TIniFile Funktionalität".Methoden
 
Ich würde gerne eine FileStream Klasse schreiben die ich wie eine IniFile behandeln kann. Wie könnte man denn sowas machen? Ich habe gedacht daß ich einen Header anlege in der ich die nötigen Infos speichere. Nur, wie könnte so ein Header aussehen? Oder ist das Ganze Blödsinn?

Sir Rufo 26. Mai 2014 13:23

AW: FileStream mit "TIniFile Funktionalität".Methoden
 
Du willst eine Klasse von
Delphi-Quellcode:
TFileStream
ableiten und dann um Methoden von
Delphi-Quellcode:
TIniFile
erweitern?

Lass mich kurz überlegen: Ja, das ist Blödsinn :)

Bjoerk 26. Mai 2014 13:36

AW: FileStream mit "TIniFile Funktionalität".Methoden
 
Juut. Einverstanden. :oops:

Dann anders rum. Wie krieg ich eine emf in eine IniFile. Auch Blödsinn?

Sir Rufo 26. Mai 2014 13:39

AW: FileStream mit "TIniFile Funktionalität".Methoden
 
Zitat:

Zitat von Bjoerk (Beitrag 1260264)
Juut. Einverstanden. :oops:

Dann anders rum. Wie krieg ich eine emf in eine IniFile. Auch Blödsinn?

Nö, du bekommst quasi alles in ein IniFile mit Delphi-Referenz durchsuchenTiniFile.WriteBinaryStream ;)

DeddyH 26. Mai 2014 13:42

AW: FileStream mit "TIniFile Funktionalität".Methoden
 
Meintest Du vielleicht eher TIniFile.WriteBinaryStream?

Bjoerk 26. Mai 2014 13:55

AW: FileStream mit "TIniFile Funktionalität".Methoden
 
Okay. Wenn das funktioniert? Wäre mir ja auch viel lieber. Ich werf mal einen Blick in die inifiles.pas. Melde mich ggf. nochmal. Thanx!

himitsu 26. Mai 2014 14:30

AW: FileStream mit "TIniFile Funktionalität".Methoden
 
TCustomIni (der Vorfahre von TIniFile) ... das kann man gern verwenden und ihm, statt der INI-Datei-WinAPI, ein anderes Backend verpassen.
TStringListe mit Names/Values (ist wie eine INI, aber mit nur einer einzigen Section)
TStringStream
TTextReader
TTextWriter
TBinaryReader
TBinaryWriter
TStringReader
TStringWriter

TStreamWriter
TStreamReader
...


Das Delphi-Referenz durchsuchenRead, Delphi-Referenz durchsuchenReadLn, Delphi-Referenz durchsuchenWrite und Delphi-Referenz durchsuchenWriteLn des alten Delphi-Referenz durchsuchenAssignFile

Bjoerk 26. Mai 2014 15:03

AW: FileStream mit "TIniFile Funktionalität".Methoden
 
Okay. Ich hab's jetzt erst mal so probiert. Funzt einwandfrei.
Delphi-Quellcode:
function TMemIniFileEx.ReadMetaFile(const Section, Name: string;
  Value: TMetaFile): integer;
var
  MemoryStream: TMemoryStream;
begin
  MemoryStream := TMemoryStream.Create;
  try
    Result := ReadBinaryStream(Section, Name, MemoryStream); // integer, kein int64
    MemoryStream.Position := 0;
    Value.LoadFromStream(MemoryStream);
  finally
    MemoryStream.Free;
  end;
end;

procedure TMemIniFileEx.WriteMetaFile(const Section, Name: string;
  Value: TMetaFile);
var
  MemoryStream: TMemoryStream;
begin
  MemoryStream := TMemoryStream.Create;
  try
    Value.SaveToStream(MemoryStream);
    MemoryStream.Position := 0;
    WriteBinaryStream(Section, Name, MemoryStream);
  finally
    MemoryStream.Free;
  end;
end;

Sir Rufo 26. Mai 2014 15:17

AW: FileStream mit "TIniFile Funktionalität".Methoden
 
Bis auf die Tatsache, dass du dich jetzt mit einem
Delphi-Quellcode:
TMemIniFile
verheiratet hast sieht das doch gut aus.

Wenn du eine Klasse geschrieben hättest, die etwas näher bei deiner Anwendung und etwas weiter weg von
Delphi-Quellcode:
TMemIniFile
ist, dann wäre das flexibler.

Delphi-Quellcode:
type
  TFoo = class( TCustomIniFile )
  private
    FIniFile : TCustomIniFile;
  public
    constructor Create( AIniFile : TCustomIniFile );

    // Alle Methoden auf die interne FIniFile umleiten

    procedure WriteMetaFile( const Section, Name : string; const Value : TMetaFile );
    procedure ReadMetaFile( const Section, Name : string; const Value : TMetaFile );
  end;

constructor TFoo.Create( AIniFile : TCustomIniFile );
begin
  inherited Create;
  if not Assigned( AIniFile )
  then
    raise EArgumentNilException.Create( 'TFoo: AIniFile' );
  FIniFile := AIniFile;
end;

procedure TFoo.WriteMetaFile( const Section, Name : string; const Value : TMetaFile );
var
  LStream : TStream;
begin
  LStream := TMemoryStream.Create;
  try
    Value.WriteToStream( LStream );
    LStream.Position := 0;
    FIniFile.WriteBinaryStream( Section, Name, LStream );
  finally
    LStream.Free;
  end;
end;

Bjoerk 26. Mai 2014 15:48

AW: FileStream mit "TIniFile Funktionalität".Methoden
 
Okay. Meistens arbeite ich aber mit einen eigenen IniFileParser. Der liest die Ini mit Assignfile und Co als TextFile ein. Wenn ich dort jetzt die Methoden (ReadMetaFile, ReadBinaryStream bzw. WriteMetaFile, SaveToStream) ergänze geht das dann noch als TextFile?
Delphi-Quellcode:
function TStrIniFile.LoadFile: boolean;
var
  F: TextFile;
  S: string;
  Buf: array [1..65536] of Char;
begin
  Result := false;
  if IniFileExists then
  begin
    AssignFile(F, FFileName);
    SetTextBuf(F, Buf);
    if CanOpenFile(F, false) then
    begin
      while not Eof(F) do
      begin
        Readln(F, S);
        if IsIniLine(S) then
          AddItem(S);
      end;
      CloseFile(F);
      Result := true;
    end;
  end;
end;

function TStrIniFile.SaveFile: boolean;
var
  F: TextFile;
  I: integer;
  Buf: array [1..65536] of Char;
begin
  Result := false;
  if FFileName <> '' then
  begin
    AssignFile(F, FFileName);
    SetTextBuf(F, Buf);
    if CanOpenFile(F, true) then
    begin
      for I := 0 to FCount - 1 do
      begin
        if I > 0 then
          if FEqualSignPos[I] < 0 then
            Writeln(F);
        Writeln(F, FItems[I]);
      end;
      CloseFile(F);
      Result := true;
    end;
  end;
end;

Sir Rufo 26. Mai 2014 16:08

AW: FileStream mit "TIniFile Funktionalität".Methoden
 
Zitat:

Zitat von Bjoerk (Beitrag 1260303)
Okay. Meistens arbeite ich aber mit einen eigenen IniFileParser. Der liest die Ini mit Assignfile und Co als TextFile ein. Wenn ich dort jetzt die Methoden (ReadMetaFile, ReadBinaryStream bzw. WriteMetaFile, SaveToStream) ergänze geht das dann noch als TextFile?

:shock: Das macht Sinn? Das musst du mir aber jetzt mal erklären, warum du nicht einfach Delphi-Referenz durchsuchenTIniFile benutzt

Bjoerk 26. Mai 2014 16:23

AW: FileStream mit "TIniFile Funktionalität".Methoden
 
Ist das verboten? Zum Beispiel weil IniFile bei jedem Wert neu abspeichert? Weil meiner schneller und umfangreicher ist? BTW, hab gesehen daß WriteBinaryStream BinToHex umwandelt. Also no Problem mit AssignFile und Co..

Neutral General 26. Mai 2014 16:41

AW: FileStream mit "TIniFile Funktionalität".Methoden
 
Zitat:

Zitat von Bjoerk (Beitrag 1260316)
Ist das verboten? Zum Beispiel weil IniFile bei jedem Wert neu abspeichert? Weil meiner schneller und umfangreicher ist? BTW, hab gesehen daß WriteBinaryStream BinToHex umwandelt. Also no Problem mit AssignFile und Co..

Es gibt eine TMemIniFile in der IniFiles.pas, die Speichert nicht jedes mal direkt auf die Platte.
(und ist daher ggf. auch schneller).

Und brauchst du wirklich eine High-Speed Ini? Wenn du so viel/oft in eine Ini schreibst oder daraus liest dann solltest du wahrscheinlich eh über Alternativen nachdenken weil eine Ini keine Datenbank ist.

Wenn es nur ab und zu mal (beim Programmstart und vllt beim Ändern irgendwelcher Einstellungen) passiert dann machen auch 100ms nix aus ;)

himitsu 26. Mai 2014 16:44

AW: FileStream mit "TIniFile Funktionalität".Methoden
 
Zitat:

Zitat von Bjoerk (Beitrag 1260295)
Okay. Ich hab's jetzt erst mal so probiert. Funzt einwandfrei.
Delphi-Quellcode:
function TMemIniFileEx.ReadMetaFile(const Section, Name: string;
  Value: TMetaFile): integer;
var
  MemoryStream: TMemoryStream;
begin
  MemoryStream := TMemoryStream.Create;
  try
    Result := ReadBinaryStream(Section, Name, MemoryStream); // integer, kein int64
...

Wobei ich hier mich etwas wundere.

Wollte man nun ein TIniFile, was nicht mit einer Datei, sondern auf einem Stream arbeitet (für den gesamten Inhalt der INI), so wie es im Titel heißt,
oder wollte man einen Stream in einem INI-Value abspeichern, so wie es in diesem Code gemacht wird?


Zitat:

Zum Beispiel weil IniFile bei jedem Wert neu abspeichert? Weil meiner schneller
Delphi-Referenz durchsuchenTMemIniFile


Man kann natürlich auch überlegen, ob man unbedingt eine INI verwenden muß, oder ob ein anderes Daten-/Dateiformat nicht auch ginge.

Bjoerk 26. Mai 2014 16:45

AW: FileStream mit "TIniFile Funktionalität".Methoden
 
Genau so ist es, Michael. Eigentlich mißbrauche ich IniFiles als Datenbank. Das kann ich auf die Schnelle aber nicht ändern. :oops:

Bjoerk 26. Mai 2014 16:47

AW: FileStream mit "TIniFile Funktionalität".Methoden
 
Zitat:

Wobei ich hier mich etwas wundere.

Wollte man nun ein TIniFile, was nicht mit einer Datei, sondern auf einem Stream arbeitet (für den gesamten Inhalt der INI), so wie es im Titel heißt,
oder wollte man einen Stream in einem INI-Value abspeichern, so wie es in diesem Code gemacht wird?
Ganz recht Himitsu. Sir Rufo ist "Schuld". :-D -> Siehe #2.

himitsu 26. Mai 2014 16:54

AW: FileStream mit "TIniFile Funktionalität".Methoden
 
Zitat:

Zitat von Bjoerk (Beitrag 1260321)
Eigentlich mißbrauche ich IniFiles als Datenbank. Das kann ich auf die Schnelle aber nicht ändern. :oops:

Doch. :mrgreen:


Du nimmst dir TCustomIniFile, baust als Backend den Zugriff auf die Datenbank ein und im Programm wird das Ding dann wie ein TIniFile verwendet ... schreibt und liest aber in Wirklichkeit in die/aus der Datenbank.

PS: Das gibt es auch schon, siehe Delphi-Referenz durchsuchenTRegIniFile, welches wie eine TIniFile aussieht, aber in Wirklichkeit die Daten in einem RegistryPfad speichert.
Danach kann man dann in Ruhe und Schrittweise die Funktionen direkt auf die DB umstellen, ohne daß der restliche alte Code gleich knallt.

Das ist einer der Vorteile der OOP ... kompatible Schnittstelle aber dahinter liegt eine unterschiedliche Funktion.

Bjoerk 28. Mai 2014 09:40

AW: FileStream mit "TIniFile Funktionalität".Methoden
 
Stimmt. Gute Idee. Die Lese und Schreibzugriffe Klassenintern an eine Datenbank delegieren (private FDatenbank: TDatenbank). Welche würde sich denn für diesen Zweck anbieten (Client Server brauch ich nicht)?

Neutral General 28. Mai 2014 09:41

AW: FileStream mit "TIniFile Funktionalität".Methoden
 
Firebird Embedded oder SQLite würde ich sagen

DeddyH 28. Mai 2014 09:44

AW: FileStream mit "TIniFile Funktionalität".Methoden
 
Prinzipiell kannst Du da jede DB nehmen, die Embedded-Modus, also ohne Serverinstallation, unterstützt (Firebird Embedded, SQLite, Absolute Database, etc.).


Alle Zeitangaben in WEZ +1. Es ist jetzt 13:03 Uhr.

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