Delphi Tokyo-我有一个文本文件...(特别是CSV文件)。我正在使用TextFile操作逐行读取文件...文件的前三个字节具有某些我不感兴趣的标头数据类型。尽管我认为所有文件都是这种情况,但我想验证一下在我删除它之前。简而言之,我想读取该行,将前三个字节与三个十六进制值进行比较,如果匹配,则删除这三个字节。
当我在十六进制编辑器中查看文件时,会看到
EF BB BF ...
无论出于何种原因,我的比较均不起作用。 这是一个代码片段。
var
LeadingBadBytes: String;
begin
// Open file, and read first line into variable TriggerHeader
...
LeadingBadBytes := '$EFBBBF';
if AnsiPos(LeadingBadBytes, TriggerHeader) = 1 then
delete(TriggerHeader, 1, 3);
DELETE命令本身可以正常工作,但是我无法使AnsiPos正常工作。我该怎么做?
答案 0 :(得分:7)
字节EF BB BF
是UTF-8 BOM,用于将文件标识为以UTF-8编码的Unicode文本。它们仅出现在文件的开头,而不是出现在每一行。
您的比较不起作用,因为您正在将读取的字符串与文字字符串 '$EFBBBF'
进行比较,而不是与字节序列 EF BB BF
进行比较。
更改此:
LeadingBadBytes := '$EFBBBF';
...
Delete(TriggerHeader, 1, 3);
对此:
LeadingBadBytes := #$FEFF; // EF BB BF is the UTF-8 encoded form of Unicode codepoint U+FEFF...
...
Delete(TriggerHeader, 1, 1); // or Delete(..., Length(LeadingBadBytes))
另外,考虑使用StrUtils.StartsText(...)
代替AnsiPos(...) = 1
。
话说回来,现代版本的Delphi应该为您处理BOM,您根本不应该在读取的数据中接收它。但是,由于您说的是使用TextFile
,因此它不是可识别BOM的AFAIK。首先,您不应该使用过时的 Pascal样式的文件I / O。尝试使用更现代的Delphi RTL I / O类,例如TStringList
或TStreamReader
,它们都支持BOM。