Tag Archives: save string unicode textfile Delphi

Saving string or stringlist to unicode text file

TextAfter moving to recent Delphis (as 2009 or newer) saving to text files has changed as strings now are full unicode. So your old code writing to textfile also must change.

If you use TStringList to write its lines to text files, you most probably used:


var StrList : TStringList;

with StrList do
begin
 Add( “Msg” );
 SaveToFile(sFileName); //your filename
end;

This won’t work in recent Delphi, if you write unicode symbols. You need to provide Encoding for your file or else you will write only ANSI text file, so rebuild you need a TEncoding class:


var StrList : TStringList;

with StrList do
begin
 Add( “Msg” );
 SaveToFile(sFileName, TEncoding.Unicode); //your unicode filename
end;

Now, if you just want to write a single string to text file. Above function will work but you need to create a StringList first.

First you need to write a Unicode preambule to a text file and sadly convert your string to UTF8 string ( or widestring), but still you will  retain your unicode symbols. Here’s a function:


procedure StringtoFileUTF8(Filename, Line: String; Append : boolean);
var
fs: TFileStream;
preamble:TBytes;
outpututf8: RawByteString;
amode: Integer;
begin
if Append and FileExists(FileName)
then amode := fmOpenReadWrite
else amode := fmCreate;
fs := TFileStream.Create(filename, { mode } amode, fmShareDenyWrite);
{ sharing mode allows read during our writes }
try

{internal Char (UTF16) codepoint, to UTF8 encoding conversion:}
outpututf8 := Utf8Encode(line); // this converts UnicodeString to WideString, sadly.

if (amode = fmCreate) then
begin
preamble := TEncoding.UTF8.GetPreamble;
fs.WriteBuffer( PAnsiChar(preamble)^, Length(preamble));
end
else
begin
fs.Seek(fs.Size, 0); { go to the end, append }
end;

outpututf8 := outpututf8 + AnsiChar(#13) + AnsiChar(#10);
fs.WriteBuffer( PAnsiChar(outpututf8)^, Length(outpututf8) );
finally
fs.Free;
end;
end;

There is also another method if you have Delphi 2010 or newer using TStreamWriter class. This is taken from embarcadero help:


procedure TMainForm.btLoadClick(Sender: TObject);
var
 Reader: TStreamReader;
begin
 { Create a new stream writer directly. }
 Reader := TStreamReader.Create( 'local_file.txt',
 TEncoding.UTF8);

 { Read the title and then the actual text. }
 edtTitle.Text := Reader.ReadLine();
 mmText.Text := Reader.ReadToEnd();

 { Close and Free the writer. }
 Reader.Free();
end;

procedure TMainForm.btSaveClick(Sender: TObject);
var
 Writer: TStreamWriter;
begin
 { Create a new stream writer directly. }
 Writer := TStreamWriter.Create('local_file.txt',
 false, TEncoding.UTF8);

 { Store the title and then the text. }
 Writer.WriteLine(edtTitle.Text);
 Writer.Write(mmText.Text);

 { Close and Free the writer. }
 Writer.Free();
end;
Advertisements