我在 Delphi 6 中使用以下函数来检测 Unicode BOM。
const
//standard byte order marks (BOMs)
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); // Allow other programs read access at the same time.
Try
FillChar(Buffer, SizeOf(Buffer), $AA);//fill with characters that we are not expecting then...
Stream.Read(Buffer, SizeOf(Buffer)); //...read up to SizeOf(Buffer) bytes - there may not be enough
//use Read rather than ReadBuffer so the no exception is raised if we can't fill 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。如果您想要这种行为,您可以使用它来阻止此类文件。
你说德尔福6TStringList
如果没有 BOM,则可以加载 16 位编码文件。虽然情况可能如此,但您会发现,对于 ASCII 范围内的字符,每隔一个字符都是#0
。我想这不是你想要的。
如果您想检测没有 BOM 的文件的文本是否为 Unicode,那么您可以使用IsTextUnicode http://msdn.microsoft.com/en-gb/library/windows/desktop/dd318672.aspx。然而,它可能会给出误报。在这种情况下,我怀疑请求原谅比许可更好。
现在,如果我是你,我实际上不会尝试阻止 Unicode 文件。我会读它们。使用 TNT Unicode 库。你想要的课程叫做TWideStringList
.