tags:

views:

1726

answers:

2

I have Delphi 2007 code that looks like this:

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

I call it like this:

var
  SourceBuffer : PChar;
  MyFile: TFileStream;

....

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

This worked in Delphi 2007, but it gives me a lot of junk characters in Delphi 2010. I know this is due to unicode compliance issues, but I am not sure how to address the issue.

Here is what I've tried so far:

  • Change the data type of SourceBuffer(and also the parameter expected by WideString) to PWideChar

  • Every one of the suggestions listed here

What am I doing wrong?

+4  A: 

You don't need a separate buffer to write a string to a stream. Probably the simplest way to do it is to encode the string to UTF8, like so:

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;

I've declared TStreamEx as a class helper for TStream, but it shouldn't be too difficult to rewrite these as a solo procedure and function like your example.

Mason Wheeler
This worked for me after I removed the "self.WriteBuffer(len, 4);" - that was writing some gibberish characters to the output file.
JosephStyons
Those "gibberish characters" are the length of the string, so the reading function knows how much to read back in. If you need this to be plain text, you'll need some other way to tell readString where to stop.
Mason Wheeler
I am writing this file out for another application to read it in, so it is not important that I be able to read it back in.
JosephStyons
In that case, make sure that the other application knows it's receiving a string in UTF8 format. Or if you don't have control over the other app, convert it to an AnsiString instead of a UTF8String. But you could lose data doing that if you're using Unicode characters outside the ANSI set.
Mason Wheeler
+3  A: 

Delphi 2010 has a nice solution for this, documented here: http://docwiki.embarcadero.com/CodeSamples/en/StreamStrRdWr%5F%28Delphi%29

John Kaster