我在 Delphi 6 中使用了下面这个函数来检测 Unicode BOM 。
const
UTF8BOM: array [0..2] of AnsiChar = #$EF#$BB#$BF;
UTF16LittleEndianBOM: array [0..1] of AnsiChar = #$FF#$FE;
UTF16BigEndianBOM: array [0..1] of AnsiChar = #$FE#$FF;
UTF32LittleEndianBOM: array [0..3] of AnsiChar = #$FF#$FE#$00#$00;
UTF32BigEndianBOM: array [0..3] of AnsiChar = #$00#$00#$FE#$FF;
function FileHasUnicodeBOM(const FileName: string): Boolean;
var
Buffer: array [0..3] of AnsiChar;
Stream: TFileStream;
begin
Stream := TFileStream.Create(FileName, fmOpenRead or fmShareDenyWrite);
Try
FillChar(Buffer, SizeOf(Buffer), $AA);
Stream.Read(Buffer, SizeOf(Buffer));
Finally
FreeAndNil(Stream);
End;
Result := CompareMem(@UTF8BOM, @Buffer, SizeOf(UTF8BOM)) or
CompareMem(@UTF16LittleEndianBOM, @Buffer, SizeOf(UTF16LittleEndianBOM)) or
CompareMem(@UTF16BigEndianBOM, @Buffer, SizeOf(UTF16BigEndianBOM)) or
CompareMem(@UTF32LittleEndianBOM, @Buffer, SizeOf(UTF32LittleEndianBOM)) or
CompareMem(@UTF32BigEndianBOM, @Buffer, SizeOf(UTF32BigEndianBOM));
end;
这将检测所有标准的BOM。如果您希望阻止此类文件,则可以使用它。
您说Delphi 6的TStringList
可以加载16位编码的文件,如果它们没有BOM。虽然可能是这种情况,但是对于ASCII范围内的字符,每隔一个字符就是#0
。我猜这不是你想要的。
如果您想检测文本是否为无BOM文件的Unicode,则可以使用IsTextUnicode
。但是,它可能会出现误报。这是一种情况,我认为寻求原谅比征得允许更好。
现在,如果我是您,我实际上不会尝试阻止Unicode文件。我会读取它们。使用TNT Unicode库。您需要的类名为TWideStringList
。