Delphi:TStringList不懂BOM?

max*_*fax 1 delphi stringstream filestream decoding

TStringList不了解BOM吗?

Tf1 := TFileStream.Create(LIGALOG+'liga.log',fmOpenRead or fmShareDenyNone);

str:=tstringlist.Create;
str.LoadFromStream(tf1);

String1:='FStream '+inttostr(tf1.Size)+'/ String: '+(str.Text);
Run Code Online (Sandbox Code Playgroud)

如果文本文件以UTF-8 + BOM保存Str.Count=0; Str.Text=''.没有BOM,一切都还可以.
这是正常的吗?

Ken*_*ite 12

如果您在2009年之前使用的是Delphi版本,它不支持Unicode,并且BOM对TStringList毫无意义.

如果您使用的是D2009或更高版本(支持Unicode),TStringList.LoadFromStream(Stream: TStream; Encoding: TEncoding)如果您提前知道编码是什么,则可以使用重载; 如果你不这样做,RTL将尝试使用它TEncoding.GetBufferEncoding.您可以在此处查看有关此主题的Delphi XE文档

如果您不提前知道,并且RTL无法从内容中找出它,您可以随时从流中读取BOM,然后将其设置Stream.Position为刚好在BOM之后并TStringList从中加载通过解码的位置,您可以从该BOM确定自己.

而且,创建一个TFileStream简单然后加载到一个TStringList是浪费; TStringList.LoadFromFile将处理文件本身,并且如果这就是你将要做的所有事情,那么代码就会少得多TStream.

编辑:在您发表评论之后,我想我会列出一份我熟悉的物料清单 - 可能还有更多我不知道的:

$00 $00 $FE $FF  UTF-32, big-endian (bytes must be swapped for Windows)
$FE $FF $00 $00  UTF-32, little-endian
$FF $FE          UTF-16 2 byte chars little-endian
$FE $FF          UTF-16 2 byte big-endian 
$EF $BB $BF      Unicode UTF-8 (must be decoded before using Unicode data)
Run Code Online (Sandbox Code Playgroud)

(供将来参考:你应该在你的问题的标签或文本中指出你正在使用哪个版本的Delphi,因为它们之间的VCL和RTL存在差异.当涉及Unicode/BOM类型问题时,这些差异非常重要.)