【发布时间】:2015-11-24 12:10:26
【问题描述】:
我在将包含德语字母的字符串保存到 txt 文件时遇到了问题。 MCVE 如下所示:
procedure TForm1.Button1Click(Sender: TObject);
var
s: string; //alias for UnicodeString
tf: textfile;
ms: tmemorystream;
begin
s := 'ßüÜöÖäÄФфшШ';
assignfile(tf, 'b:\tmp.txt');
Rewrite(tf);
write(tf, s);
closefile(tf);
ms := tmemorystream.Create;
try
ms.WriteBuffer(Pointer(s)^, Length(s) * SizeOf(s[Low(s)]));
ms.Position := 0;
ms.SaveToFile('b:\tmp2.txt');
finally
ms.Free;
end;
end;
如果字符串直接保存到文件中,我们会得到以下信息:tmp.txt – ?uUoOaAФфшШ。尽管西里尔字母仍然存在,但德语字母已更改。如果字符串由 TMemoryStream 保存,则结果是正确的:tmp2.txt – ßüÜöÖäÄФфшШ。这是什么原因?
附加
我决定为以不同方式保存的给定字符串添加 HEX 值:
对于Write 方法:
data: array[0..10] of byte = (
$3F, $75, $55, $6F, $4F, $61, $41, $D4, $F4, $F8, $D8
);
对于在AssignFile(tf, 'b:\tmp.txt',CP_UTF8); 之后调用的Write 方法:
data: array[0..21] of byte = (
$C3, $9F, $C3, $BC, $C3, $9C, $C3, $B6, $C3, $96, $C3, $A4, $C3, $84, $D0, $A4,
$D1, $84, $D1, $88, $D0, $A8
);
对于TMemoryStream:
data: array[0..21] of byte = (
$DF, $00, $FC, $00, $DC, $00, $F6, $00, $D6, $00, $E4, $00, $C4, $00, $24, $04,
$44, $04, $48, $04, $28, $04
);
对于TStringList:
data: array[0..27] of byte = (
$FF, $FE, $DF, $00, $FC, $00, $DC, $00, $F6, $00, $D6, $00, $E4, $00, $C4, $00,
$24, $04, $44, $04, $48, $04, $28, $04, $0D, $00, $0A, $00
);
附加
根据@Remy-Lebeau 的宝贵建议:
此方法生成一个 25 字节长的文件。这与在AssignFile(tf, 'b:\tmp.txt',CP_UTF8); 之后调用的 Write 方法生成的 HEX 类似,额外增加了 3 个字节(BOM?)。
data: array[0..24] of byte = (
$EF, $BB, $BF, $C3, $9F, $C3, $BC, $C3, $9C, $C3, $B6, $C3, $96, $C3, $A4, $C3,
$84, $D0, $A4, $D1, $84, $D1, $88, $D0, $A8
);
【问题讨论】:
-
谢谢@LU-RD。我有德尔福 XE5。你的评论帮助了我。该代码与以下行正常工作:
assignfile(tf, 'b:\tmp.txt',CP_UTF8);请发布答案,以便我接受。 -
我猜你需要决定的是你希望如何编码你的文本。你应该积极地做出这个决定。
-
谢谢你,@DavidHeffernan。我是否正确理解将字符串变量写入文件需要明确指示编码?但这是否意味着编写包含
records和strings(固定长度)的File of somerecord会导致数据损坏? -
简单问题。你想为你的文本使用什么编码。
标签: string delphi unicode localization