Einzelnen Beitrag anzeigen

Andreas13

Registriert seit: 14. Okt 2006
Ort: Nürnberg
711 Beiträge
 
Delphi XE5 Professional
 
#4

AW: Stream String lesen und schreiben

  Alt 1. Okt 2023, 12:32
Hallo Stahli,

ich benutze folgeden Code um die Inhalte divereser dynamischer Arrays (= "Vektoren") als AnsiString in Streams zu speichern und aus diesen daraus zu laden:
Delphi-Quellcode:
Type
  TDynStringVektor = TArray<String>;
  PDBiA_StreamType = Int32;

CONST
  PDBiA_StreamType_Integer = 32000;
  PDBiA_StreamType_Double = PDBiA_StreamType_Integer + 200;
  PDBiA_StreamType_Extended = PDBiA_StreamType_Integer + 400;
  PDBiA_StreamType_String = PDBiA_StreamType_Integer + 600;
  PDBiA_StreamType_MPAF_String = PDBiA_StreamType_Integer + 800;
  ...

Procedure WriteStringVektor_To_Stream(CONST Quelle: TDynStringVektor; Stream: TBytesStream);
// Dynamisches String-Array in einen Stream umwandeln

{ Struktur des Streams, der nur Byte-weise gelesen werden kann:

  ----------------------
  0. StreamType          : Int32 (nach eigener Definition)
  ----------------------
  1. Länge des Arrays    : Int32
  ----------------------
  2. Länge von String_1  : Int32
  3. String_1            : String variabler Länge
  ----------------------
  4. Länge von String_2  : Int32
  5. String_2            : String variabler Länge
  ----------------------
  6. Länge von String_3  : Int32
  7. String_3            : String variabler Länge
  ----------------------
    ...
    ...
  ----------------------
 
  n-1. Länge vom LETZTEN String  : Int32
  n.  LETZTER String            : String variabler Länge
  ----------------------
}



VAR
  Len : Int32;
  StreamType: PDBiA_StreamType;
  S : AnsiString;
    
Begin
  Stream.Position:= 0; // Wichtig!!
  
  StreamType:= PDBiA_StreamType_String;

  Stream.WriteBuffer(StreamType, SizeOf(StreamType)); // Header-Eintrag (= Int32) im Stream: StreamTyp
  
  Len:= Length(Quelle);
  Stream.WriteBuffer(Len, SizeOf(Len)); // Erster Eintrag (= Int32) im Stream: Länge des Arrays:

  IF Len < 0 Then Begin // Fehlerhafter Eintrag im Stream
    Fehlermeldung('Stream-Fehler: Negative Array-Länge!');
    Exit;
  End;
  
  IF Len = 0 Then // Leeres Array:
    Exit; // Fertig --> Es wird nur die Länge (= 0) in den Stream geschrieben, mehr nicht!
    
  For S in Quelle Do Begin // Für jeden String im String-Array wiederholen
    Len:= Length(S); // Strings werden der Reihe nach eingelesen
    Stream.WriteBuffer(Len, SizeOf(Len)); // Länge des aktuellen Strings (dynamisch: d.h. jedes Element könnte unterschiedlich lang sein)

    IF Len <> 0 Then Begin
      Stream.WriteBuffer(S[1], Len*SizeOf(S[1])); // String speichern. Zählung bei Strings: 1-basiert! Daher S[1] --> Erstes Zeichen im dynamischen String
    End;
  End;
End;{WriteStringVektor_To_Stream}
{-------------------------------}

Function LoadStingVektor_From_Stream(Stream: TBytesStream): TDynStringVektor;
// Dynamisches String-Array aus einem Stream laden

{ Struktur des Streams, der nur Byte-weise gelesen werden kann:

  ----------------------
  0. StreamType          : Int32 (nach eigener Definition)
  ----------------------
  1. Länge des Arrays    : Int32
  ----------------------
  2. Länge von String_1  : Int32
  3. String_1            : String variabler Länge
  ----------------------
  4. Länge von String_2  : Int32
  5. String_2            : String variabler Länge
  ----------------------
  6. Länge von String_3  : Int32
  7. String_3            : String variabler Länge
  ----------------------
    ...
    ...
  ----------------------
 
  n-1. Länge vom LETZTEN String  : Int32
  n.  LETZTER String            : String variabler Länge
  ----------------------
}


VAR
  i, Len : Int32;
  StreamType: PDBiA_StreamType;
  
Begin
  Stream.Position:= 0; // Wichtig!!

  Stream.ReadBuffer(StreamType, SizeOf(StreamType)); // Header-Eintrag (= Int32) im Stream: StreamTyp


  Len:= SizeOf(Len);
  Stream.ReadBuffer(Len, Len); // Erster Eintrag (= Int32) im Stream: Länge des Arrays:

  IF Len < 0 Then Begin // Fehlerhafter Eintrag im Stream
    Fehlermeldung('Stream-Fehler: Negative Array-Länge!');
    Exit;
  End;

  IF Len = 0 Then Begin // Leeres Array:
    Exit; // Fertig --> Es stand nur die Länge (= 0) in den Stream geschrieben, mehr nicht!
  End;

  SetLength(Result, Len);
  
  For i:= 0 To Len-1 Do Begin// 0: dynamisches Array ist NULL-basiert!
    Stream.ReadBuffer(Len, SizeOf(Len)); // Länge des aktuellen Strings (dynamisch: d.h. jedes Element könnte unterschiedlich lang sein)

    IF Len < 0 Then Begin // Fehlerhafter Eintrag im Stream
      Fehlermeldung('Stream-Fehler: Negative String-Länge!');
      Exit;
    End;

   IF Len > 0 Then Begin
     SetLength(Result[i], Len);
     Stream.ReadBuffer(Result[i][1], Len*SizeOf(Char)); // 1: ERSTES Zeichen des Strings
   End;
  End;
End;{LoadStingVektor_From_Stream}
{-------------------------------}
Grüße, Andreas
Wenn man seinem Nächsten einen steilen Berg hinaufhilft, kommt man selbst dem Gipfel näher. (John C. Cornelius)
  Mit Zitat antworten Zitat