Plutôt que de lire et d'écrire un personnage à la fois, lisez et écrivez-les tous en même temps :
procedure WriteWideString(const ws: WideString; stream: TStream);
var
nChars: LongInt;
begin
nChars := Length(ws);
stream.WriteBuffer(nChars, SizeOf(nChars);
if nChars > 0 then
stream.WriteBuffer(ws[1], nChars * SizeOf(ws[1]));
end;
function ReadWideString(stream: TStream): WideString;
var
nChars: LongInt;
begin
stream.ReadBuffer(nChars, SizeOf(nChars));
SetLength(Result, nChars);
if nChars > 0 then
stream.ReadBuffer(Result[1], nChars * SizeOf(Result[1]));
end;
Maintenant, techniquement, puisque WideString
est un programme Windows BSTR
il peut contenir un étrange nombre d'octets. Le site Length
lit le nombre d'octets et le divise par deux, il est donc possible (mais peu probable) que le code ci-dessus coupe le dernier octet. Vous pouvez utiliser ce code à la place :
procedure WriteWideString(const ws: WideString; stream: TStream);
var
nBytes: LongInt;
begin
nBytes := SysStringByteLen(Pointer(ws));
stream.WriteBuffer(nBytes, SizeOf(nBytes));
if nBytes > 0 then
stream.WriteBuffer(Pointer(ws)^, nBytes);
end;
function ReadWideString(stream: TStream): WideString;
var
nBytes: LongInt;
buffer: PAnsiChar;
begin
stream.ReadBuffer(nBytes, SizeOf(nBytes));
if nBytes > 0 then begin
GetMem(buffer, nBytes);
try
stream.ReadBuffer(buffer^, nBytes);
Result := SysAllocStringByteLen(buffer, nBytes)
finally
FreeMem(buffer);
end;
end else
Result := '';
end;
Inspiré par La réponse de Mghie J'ai remplacé mon Read
y Write
appels avec ReadBuffer
y WriteBuffer
. Ces derniers lèvent des exceptions s'ils ne parviennent pas à lire ou à écrire le nombre d'octets demandé.