首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >非ANSI文件的TStringList行为

非ANSI文件的TStringList行为
EN

Stack Overflow用户
提问于 2013-04-26 23:44:30
回答 1查看 1.2K关注 0票数 5

在我的应用程序中,当我想导入文件时,我使用TStringList。

但是,当有人从Excel导出数据时,文件编码是UCS-2 Little Endian,TStringList无法读取数据。

有没有办法验证这种情况,识别文本编码,并向用户发送警告,说明提供的文本不兼容?

为了清楚起见,用户将只提供简单的text..letter和数字,否则,我必须发送警告。

没有BOM的Unicode文件是好的。(TStringList可以阅读!)

ANSI文件也是。(TStringList可以阅读!)

如果有一种方法可以删除它,那么即使是带有BOM的Unicode也会很好。(TStringList可以读懂它,但是使用"i“、">>”和"reverse ?“字符,属于BOM字节)

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-04-27 00:01:56

我在Delphi6中使用了以下函数来检测Unicode BOM。

代码语言:javascript
复制
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表。如果这是你想要的行为,你可以用它来阻止这样的文件。

您指出,如果没有TStringList,Delphi6BOM可以加载16位编码的文件。虽然情况可能是这样,但您会发现,对于ASCII范围内的字符,其他所有字符都是#0。我猜这不是你想要的。

如果您想要检测没有BOM的文件的文本是否为Unicode,那么您可以使用IsTextUnicode。但是,它可能会给出假阳性。在这种情况下,我认为请求宽恕比请求许可更好。

现在,如果我是你,我实际上不会尝试阻止Unicode文件。我会读一读。使用TNT Unicode库。您需要的类称为TWideStringList

票数 7
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/16240354

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档