XE2 以降でAssignFile()
は、出力ファイルのコードページを設定するオプションのCodePage
パラメーターがあります。
function AssignFile(var F: File; FileName: String; [CodePage: Word]): Integer; overload;
Write()
どちらも入力Writeln()
をサポートするオーバーロードを持っています。UnicodeString
WideChar
CP_UTF8
そのため、コードページが に設定されたファイルを作成するWrite/ln()
と、ファイルに書き込むときに Unicode 文字列が自動的に UTF-8 に変換されます。
欠点はAnsiChar
、個々のバイトが UTF-8 に変換され、正しく書き込まれないため、値を使用して UTF-8 BOM を書き込むことができなくなることです。U+FEFF
BOMを個々のバイトとしてではなく、単一の Unicode 文字 (これが実際の文字です) として記述することで、これを回避できます。
これは XE2 で機能します。
procedure TForm1.Button1Click(Sender: TObject);
var
Outfile: TextFile;
begin
AssignFile(Outfile, 'test_chinese.txt', CP_UTF8);
Rewrite(Outfile);
//This is the UTF-8 BOM
Write(Outfile, #$FEFF);
Writeln(Outfile, '总结');
Writeln(Outfile, '°C');
CloseFile(Outfile);
end;
そうは言っても、D2009 と XE2 の間でより互換性と信頼性が高いものが必要な場合は、TStreamWriter
代わりに次を使用します。
procedure TForm1.Button1Click(Sender: TObject);
var
Outfile: TStreamWriter;
begin
Outfile := TStreamWriter.Create('test_chinese.txt', False, TEncoding.UTF8);
try
Outfile.WriteLine('总结');
Outfile.WriteLine('°C');
finally
Outfile.Free;
end;
end;
または、ファイル I/O を手動で実行します。
procedure TForm1.Button1Click(Sender: TObject);
var
Outfile: TFileStream;
BOM: TBytes;
procedure WriteBytes(const B: TBytes);
begin
if B <> '' then Outfile.WriteBuffer(B[0], Length(B));
end;
procedure WriteStr(const S: UTF8String);
begin
if S <> '' then Outfile.WriteBuffer(S[1], Length(S));
end;
procedure WriteLine(const S: UTF8String);
begin
WriteStr(S);
WriteStr(sLineBreak);
end;
begin
Outfile := TFileStream.Create('test_chinese.txt', fmCreate);
try
WriteBytes(TEncoding.UTF8.GetPreamble);
WriteLine('总结');
WriteLine('°C');
finally
Outfile.Free;
end;
end;