Delphi 7,TFileStream无法打开带有特殊字符

时间:2015-06-21 14:17:49

标签: delphi delphi-7

这一行:

TFileStream.Create(fileName, fmOpenRead or fmShareDenyNone);
如果文件名包含ñ

之类的内容,则

会丢弃例外

4 个答案:

答案 0 :(得分:4)

您最终调用CreateFileA ANSI API,并且您使用的字符没有ANSI编码。除此之外的唯一方法是使用Unicode API CreateFileW打开文件。

你可能没有意识到你打电话给CreateFileA,但这就是Delphi 7文件流的实现方式。

解决问题的一种简单方法是升级到最新的Delphi,它对本机Windows Unicode API有很好的支持。

如果您遇到ANSI Delphi,那么您仍然需要致电CreateFileW。您可以这样做来创建文件句柄。您需要将UTF-16字符串传递给该API。使用WideString存储它。您还需要以UTF-16格式从用户处获取文件名。这意味着拨打GetOpenFileNameWIFileDialog。通过将文件句柄传递给THandleStream来创建流。

为了实现这一切,您将使用TNT Unicode库。它们运作良好,但会对你施加一个大口。

坦率地说,正确的方法是使用支持Unicode的现代工具。

答案 1 :(得分:4)

您可以使用TntUnicode单元在Delphi 7下获得UTF8支持。 将TntClasses添加到您的使用中并进行如下调用:

TTntFileStream.Create(fileName, fmOpenRead or fmShareDenyNone);

确保fileName是宽字符串。

在这里您可以获得TntUnicode的副本: https://github.com/rofl0r/TntUnicode

答案 2 :(得分:2)

UTF16可以被视为代码页,就像所有可能的ANSI代码页一样。

正如Remy在评论中提到的那样,假设您的ANSI代码页支持Unicode字符串中所需的字符,您只需将该字符串的Unicode版本转换为等效的ANSI代码页版本。

Delphi编译器可以自动为您进行简单的转换,只需将 WIDEString (UTF16)转换为( ANSI 即可串

const
  WIDE_FILENAME : WIDEString = 'fuññy.txt';
var
  sFilename: String;
  strm: TFileStream;
begin
  sFilename := String(WIDE_FILENAME);

  strm := TFileStream.Create(sFilename, fmOpenRead);
  // etc
end;      

即使在(例如)Delphi 7上也能很好地工作。唯一需要注意的是所涉及的代码页(系统默认值)必须支持Unicode字符串中的扩展字符。

注意:以上代码明确使用String类型而不是 ANSIString 。在 String ANSIString 的Delphi版本中,这具有所需的效果,但也可移植到 String UnicodeString (如果您以后升级版本)。

如果在这种情况下明确使用 ANSIString ,则在升级时,结果将为转换:

// Unicode compiler using ANSIString type....
var
  sFilename: ANSIString;
begin
  sFilename := ANSIString(WIDE_FILENAME);            // Codepage conversion from UTF16 to ANSI
  strm := TFileStream.Create(sFilename, fmOpenRead); // Will implicitly convert *back* from ANSI to WIDE

// Unicode compiler using String type....
var
  sFilename: String;
begin
  sFilename := String(WIDE_FILENAME);                // String type conversion from WideString to UnicodeString
  strm := TFileStream.Create(sFilename, fmOpenRead); // No further conversion necessary

答案 3 :(得分:-1)

最佳解决方案是使用Unicode,但如果这不是一个选项,您仍然可以解决问题。

在Windows中,您可以设置用于非Unicode程序的代码页。只需更改它以支持正确的语言(西班牙语?)。然后代码应该可以工作。

  • Windows 7:控制面板>地区和语言>行政>非Unicode程序的语言

  • Windows XP:控制面板>区域和语言>高级>非Unicode程序的语言