Écrire une chaîne sur un TFileStream dans Delphi 2010
-
07-07-2019 - |
Question
J'ai du code Delphi 2007 qui ressemble à ceci:
procedure WriteString(Stream: TFileStream; var SourceBuffer: PChar; s: string);
begin
StrPCopy(SourceBuffer,s);
Stream.Write(SourceBuffer[0], StrLen(SourceBuffer));
end;
Je l'appelle comme ceci:
var
SourceBuffer : PChar;
MyFile: TFileStream;
....
SourceBuffer := StrAlloc(1024);
MyFile := TFileStream.Create('MyFile.txt',fmCreate);
WriteString(MyFile,SourceBuffer,'Some Text');
....
Cela a fonctionné dans Delphi 2007, mais cela me donne beaucoup de caractères indésirables dans Delphi 2010. Je sais que cela est dû à des problèmes de conformité unicode, mais je ne sais pas comment résoudre ce problème.
Voici ce que j'ai essayé jusqu'à présent:
-
Changer le type de données de SourceBuffer (et aussi le paramètre attendu par WideString) à PWideChar
-
Chacune des suggestions répertoriées ici
Qu'est-ce que je fais de travers?
La solution
Vous n'avez pas besoin d'un tampon séparé pour écrire une chaîne dans un flux. La manière la plus simple de le faire est probablement de coder la chaîne en UTF8, comme suit:
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;
J'ai déclaré TStreamEx comme aide de classe pour TStream, mais il ne devrait pas être trop difficile de les réécrire en tant que procédure solo et fonctionne comme votre exemple.
Autres conseils
Delphi 2010 a une solution intéressante à cet égard, documentée ici:
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();