delphi 如何检测用户选择的.txt文件是Unicode/UTF-8格式,并转换为ANSI

rkue9o1l  于 2022-12-23  发布在  其他
关注(0)|答案(1)|浏览(432)

bounty将在16小时后过期。回答此问题可获得+200声望奖励。Tom希望引起更多人对此问题的关注:可接受的答案是在Delphi 7中编译的ReturnAsAnsiText()函数

我的非Unicode Delphi 7应用程序允许用户打开.txt文件。
有时试图打开UTF-8/UNICODE .txt文件会导致问题。
我需要一个功能,检测用户是否打开UTF-8或Unicode编码的txt文件,并将其转换为系统的默认代码页(ANSI)编码时,自动可能,以便它可以由应用程序使用。
在无法转换的情况下,函数应返回错误。
ReturnAsAnsiText(filename)函数打开txt文件,检测转换,步骤如下;

  • 如果字节流没有x7 F(其ANSI)上的字节值,则按原样返回
  • 如果字节流的字节值超过x7 F,则从UTF-8转换
  • 如果流中有BOM;尝试Unicode转换
  • 如果无法转换为系统的当前代码页,则返回NULL以指示错误。

用户只能打开与其区域/代码页匹配的文件(非Unicode应用程序的控制面板区域设置),这将是此功能的一个OK限制。

rbpvctlc

rbpvctlc1#

您所设计的转换函数ReturnAsAnsiText将有许多问题:

  • Delphi 7应用程序可能无法打开文件名使用UTF-8或UTF-16的文件。
  • UTF-8(和其他Unicode)的使用率自2019年以来显著增加。Current web pages的UTF-8使用率在98%到100%之间,具体取决于语言。
  • 您的设计将错误地转换符合标准的设计所能处理的某些文本。

创建ReturnAsAnsiText超出了答案的范围,但您应该考虑定位一个可以使用的库,而不是创建一个新函数。我没有使用过 Delphi 2005(我相信它是7),但我可以使用found this MIT licensed library。它有许多警告:

  • 它不支持所有形式的BOM。
  • 它不支持所有编码。
  • 单字节字符集没有通用的“最适合”行为。

还有一些与described in this question无关的问题,您不会使用外部命令,但我在这里使用了一个命令来说明这一点:

% iconv -f utf-8 -t ascii//TRANSLIT < hello.utf8
^h'elloe
iconv: (stdin):1:6: cannot convert
% iconv -f utf-8 -t ascii < hello.utf8
iconv: (stdin):1:0: cannot convert

在基于标准的库中启用TRANSLIT支持将é这样的字符转换为ASCII e。但是对于π这样的字符仍然失败,因为没有类似形式的ASCII字符。

相关问题