Writing a string to a TFileStream in Delphi 2010
Solution 1
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.
Solution 2
Delphi 2010 has a nice solution for this, documented here:
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();
JosephStyons
I started out as a professional developer using Delphi and Oracle in a Win32 client-server environment for a manufacturing company. I worked for five years in consulting, implementing solutions for dozens of clients and using many disparate technologies. Since then, I've worked for and with the non-profit industry, building applications that help them move their missions forward. My bread-and-butter is VB.NET and C# against a SQL Server back-end using a SOA architecture. But I can and will use whatever tool gets the job done, and I've had fun doing so with Angular, jQuery, ASP.NET, PHP, and even my own homemade frameworks to deliver solutions against that platform.
Updated on June 04, 2020Comments
-
JosephStyons almost 4 years
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?
-
JosephStyons over 14 yearsThis worked for me after I removed the "self.WriteBuffer(len, 4);" - that was writing some gibberish characters to the output file.
-
Mason Wheeler over 14 yearsThose "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.
-
JosephStyons over 14 yearsI 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.
-
Mason Wheeler over 14 yearsIn 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.
-
jonjbar about 13 yearsLink is broken. Looks like this one: docwiki.embarcadero.com/CodeExamples/en/…
-
John Kaster about 13 yearsJohn, thanks for the correction to the link. Looks like a violation of the golden rule for websites - never break a permalink. Particularly for a trivial url rename like this one.
-
Kapytanhook over 8 yearsplease add the explanation that it prefixes the length, I too was using it to output a textfile and didn't know the first 4 bytes where length.