Escribir una cadena en un TFileStream en Delphi 2010
-
07-07-2019 - |
Pregunta
Tengo el código Delphi 2007 que se ve así:
procedure WriteString(Stream: TFileStream; var SourceBuffer: PChar; s: string);
begin
StrPCopy(SourceBuffer,s);
Stream.Write(SourceBuffer[0], StrLen(SourceBuffer));
end;
Lo llamo así:
var
SourceBuffer : PChar;
MyFile: TFileStream;
....
SourceBuffer := StrAlloc(1024);
MyFile := TFileStream.Create('MyFile.txt',fmCreate);
WriteString(MyFile,SourceBuffer,'Some Text');
....
Esto funcionó en Delphi 2007, pero me da muchos caracteres basura en Delphi 2010. Sé que esto se debe a problemas de cumplimiento de Unicode, pero no estoy seguro de cómo abordar el problema.
Esto es lo que he intentado hasta ahora:
-
Cambiar el tipo de datos de SourceBuffer (y también el parámetro esperado por WideString) a PWideChar
-
Todas las sugerencias enumeradas aquí
¿Qué estoy haciendo mal?
Solución
No necesita un búfer separado para escribir una cadena en una secuencia. Probablemente la forma más sencilla de hacerlo es codificar la cadena a UTF8, de esta manera:
procedure TStreamEx.writeString(const data: string);
var
len: cardinal;
oString: UTF8String;
begin
oString := UTF8String(data);
len := length(oString);
self.WriteBuffer(len, 4);
if len > 0 then
self.WriteBuffer(oString[1], len);
end;
function TStreamEx.readString: string;
var
len: integer;
iString: UTF8String;
begin
self.readBuffer(len, 4);
if len > 0 then
begin
setLength(iString, len);
self.ReadBuffer(iString[1], len);
result := string(iString);
end;
end;
He declarado TStreamEx como un ayudante de clase para TStream, pero no debería ser demasiado difícil reescribirlos como un procedimiento en solitario y funcionar como su ejemplo.
Otros consejos
Delphi 2010 tiene una buena solución para esto, documentada aquí:
http://docwiki.embarcadero.com/CodeExamples/en/StreamStrRdWr_% 28Delphi% 29
var
Writer: TStreamWriter;
...
{ Create a new stream writer directly. }
Writer := TStreamWriter.Create('MyFile.txt', false, TEncoding.UTF8);
Writer.Write('Some Text');
{ Close and free the writer. }
Writer.Free();