gpt4 book ai didi

delphi - XE2 和 Delphi 2009 之间的 unicode 文本文件输出不同吗?

转载 作者:行者123 更新时间:2023-12-03 14:44:53 24 4
gpt4 key购买 nike

当我尝试下面的代码时,与 D2009 相比,XE2 中的输出似乎有所不同。

procedure TForm1.Button1Click(Sender: TObject);
var Outfile:textfile;
myByte: Byte;

begin
assignfile(Outfile,'test_chinese.txt');
Rewrite(Outfile);

for myByte in TEncoding.UTF8.GetPreamble do write(Outfile, AnsiChar(myByte));
//This is the UTF-8 BOM

Writeln(Outfile,utf8string('总结'));
Writeln(Outfile,'°C');
Closefile(Outfile);
end;

在 Windows 8 PC 上使用 XE2 进行编译可在写字板中显示

??

txt十六进制代码:EF BB BF 3F 3F 0D 0A B0 43 0D 0A

在 Windows XP PC 上使用 D2009 进行编译可在写字板中显示

总结℃

txt十六进制代码:EF BB BF E6 80 BB E7 BB 93 0D 0A B0 43 0D 0A

我的问题是为什么它不同以及如何使用旧的文本文件 I/O 将中文字符保存到文本文件?

谢谢!

最佳答案

从 XE2 开始,AssignFile()有一个可选的 CodePage 参数,用于设置输出文件的代码页:

function AssignFile(var F: File; FileName: String; [CodePage: Word]): Integer; overload;

Write()Writeln() 都有支持 UnicodeStringWideChar 输入的重载。

因此,您可以创建一个文件,将其代码页设置为 CP_UTF8,然后 Write/ln() 在写入时会自动将 Unicode 字符串转换为 UTF-8将它们写入文件。

缺点是您将无法再使用 AnsiChar 值写入 UTF-8 BOM,因为各个字节将转换为 UTF-8,因此无法正确写入。您可以通过将 BOM 写为单个 Unicode 字符(它的真正含义 - U+FEFF)而不是单个字节来解决这个问题。

这适用于 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;

关于delphi - XE2 和 Delphi 2009 之间的 unicode 文本文件输出不同吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14232900/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com