Запись строки в TFileStream в Delphi 2010 - PullRequest
13 голосов
/ 16 сентября 2009

У меня есть код Delphi 2007, который выглядит следующим образом:

procedure WriteString(Stream: TFileStream; var SourceBuffer: PChar; s: string);
begin
  StrPCopy(SourceBuffer,s);
  Stream.Write(SourceBuffer[0], StrLen(SourceBuffer));
end;

Я называю это так:

var
  SourceBuffer : PChar;
  MyFile: TFileStream;

....

SourceBuffer := StrAlloc(1024);
MyFile := TFileStream.Create('MyFile.txt',fmCreate);
WriteString(MyFile,SourceBuffer,'Some Text');
....

Это сработало в Delphi 2007, но в Delphi 2010 у меня появилось много ненужных символов. Я знаю, что это связано с проблемами соответствия Unicode, но я не уверен, как решить эту проблему.

Вот что я пробовал до сих пор:

Что я делаю не так?

Ответы [ 2 ]

16 голосов
/ 16 сентября 2009

Вам не нужен отдельный буфер для записи строки в поток. Вероятно, самый простой способ сделать это - закодировать строку в UTF8, например так:

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;

Я объявил TStreamEx в качестве помощника класса для TStream, но не должно быть слишком сложно переписать их как процедуру соло и функцию, как в вашем примере.

14 голосов
/ 11 ноября 2009

Delphi 2010 имеет хорошее решение для этого, документированное здесь:

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();
...