Um mal auf die Kompatibilität mit neueren/zuküftigen Delphi-Versionen auf Unicodebasis einzugehen
und um da Fehler schon jetzt auszuschließen ...
Man bedenke, daß ein String dort als WideString/UnicodeString definiert ist,
wärend in einem älterem "
Ansi"-Delphi der String als AnsiString definiert wurde.
(und in Delphi 1 wohl als ShortString
)
Im Grunde ist es sowieso bei jeder langlebigen externen Speicherung und bei der Datenübertragung besser, wenn man schon wärend der Definition seiner Daten, sich da direkt auf die fundamentalen Typen beschränkt, welche sie nie ändern werden.
> String, Char, Integer und Cardinal fallen da schonmal weg,
da diese an die jeweils unterstützt Plattform angepasst werden.
Wie es bisher wohl Viele machen:
Hier kann/wird es irgendwann mal Probleme geben, wenn man es in einer anderen Delphi-Version kompilieren will!
Delphi-Quellcode:
Var S: String;
// speichern
SizeInByte := Length(S);
Stream.WriteBuffer(S[1], SizeInByte);
// lesen
SetLength(S, SizeInByte);
Stream.WriteBuffer(S[1], SizeInByte);
Als
AnsiString:
- dieses arbeitet in allen Delphiversionen gleich
- aber es bietet keine UnicodeUnterstützung in neueren Delphi
- dafür sind die gespeicherten Daten auch zwischen den verschiedenen Delphiversionen kompatibel
> hier wurde praktisch nur der String-Typ festgelegt und alles Andere bleibt gleich
Delphi-Quellcode:
Var S: AnsiString;
// Speichern
SizeInByte := Length(S);
if SizeInByte > 0 then Stream.WriteBuffer(S[1], SizeInByte);
// Lesen
SetLength(S, SizeInByte);
if SizeInByte > 0 then Stream.WriteBuffer(S[1], SizeInByte);
Als
WideString/UnicodeString:
- dieses arbeitet in allen Delphiversionen gleich
- aber es bietet die
Ansi-Unterstützung nur indirekt
- dafür sind die gespeicherten Daten ebenfalls zwischen den verschiedenen Delphiversionen kompatibel
Delphi-Quellcode:
Var S: WideString; // oder UnicodeString
// Speichern
SizeInByte := Length(S) * 2;
if SizeInByte > 0 then Stream.WriteBuffer(S[1], SizeInByte);
// Lesen
SetLength(S, SizeInByte div 2);
if SizeInByte > 0 then Stream.WriteBuffer(S[1], SizeInByte);
// sichereres Lesen, falls SizeInByte nicht immer ein vielfaches von 2 ist
SetLength(S, (SizeInByte + 1) div 2);
if SizeInByte > 0 then begin
S[Length(S)] := #0; // damit im Notfall das letzte Zeichen nicht teilweise undefiniert ist
Stream.WriteBuffer(S[1], SizeInByte);
end;
Weiterhin als
String:
- dieses arbeitet einigen Delphiversionen
unterschiedlich, da sich ja String-Typ unterscheidet
- es unterstützt immer den Standardtypen in der jeweiligen Delphi-Version
- die gespeicherten Daten nur in Delphiversionen kompatibel, welche den selben Standard-String-Typen besitzen
- dieses würde sogar
Unicode4 unterstützen
, wenn es denn mal von Delphi verwendet würde, was wohl bald mal der Fall sein könnte
Delphi-Quellcode:
Var S: String;
// Speichern
SizeInByte := Length(S) * SizeOf(Char);
if SizeInByte > 0 then Stream.WriteBuffer(S[1], SizeInByte);
// Lesen
SetLength(S, (SizeInByte + 1) div SizeOf(Char));
if SizeInByte > 0 then Stream.WriteBuffer(S[1], SizeInByte);
// sichereres Lesen, falls SizeInByte nicht immer ein vielfaches von SizeOf(Char) ist
SetLength(S, (SizeInByte + SizeOf(Char) - 1) div SizeOf(Char);
if SizeInByte > 0 then begin
S[Length(S)] := #0; // damit im Notfall das letzte Zeichen nicht teilweise undefiniert ist
Stream.WriteBuffer(S[1], SizeInByte);
end;
Ansonsten verhält es sich bei allen anderen Block-Leseverfahren genauso, außer daß dort einfach nur andere Schreib-/Lesebefehle verwendet werden.