FileExists返回true,但文件不存在

时间:2019-03-29 19:41:23

标签: delphi delphi-7

我用Delphi 7编写程序。我只需要使用它就可以处理非Unicode文件名。如果找到Unicode文件名,则应该忽略它。

我的代码如下:

var Filename: String;

if not FileExists(Filename) then Exit;

F := TFileStream(Filename, fmOpenRead or fmShareDenyWrite);

但是,对于某些Unicode文件名,FileExists()返回true,但随后TFileStream会引发异常,因为路径无效。

例如: 名为“ loop轮纹.jpg”的文件作为“ loop ??。jpg”读入文件名。这是预期的行为。 TFileStream无法读取此类文件(因为目录中没有“ loop ??。jpg”)并引发异常。但是FileExists()应该知道该文件不存在。为什么不起作用?因为它定义为:

function FileExists(const FileName: string): Boolean;
begin
  Result := FileAge(FileName) <> -1;
end;

和FileAge()定义为:

function FileAge(const FileName: string): Integer;
var
  Handle: THandle;
  FindData: TWin32FindData;
  LocalFileTime: TFileTime;
begin
  Handle := FindFirstFile(PChar(FileName), FindData);
...

FindFirstFile使用“ loop ??。jpg”作为掩码,然后找到“ loop轮纹.jpg”。

所以问题很简单:

1)我可以在Delphi 7中以某种方式轻松地在TFileStream中使用Unicode文件名吗?

2)应该使用什么功能代替FileExists以获得正确的结果?

1 个答案:

答案 0 :(得分:11)

  1. 不是TFileStream本身,不是。但是,您可以改用Win32 CreateFileW()打开Unicode文件名,然后将返回的HANDLE分配给THandleStream。这实际上就是TFileStream内部所做的事情(在Delphi 7中使用CreateFileA()代替)。

  2. 较新版本的Delphi在实现FileAge()时使用Win32 GetFileAttributes() 1 而不是RTL的FileExists()GetFileAttributes()不像FindFirstFile()那样支持通配符。

    1。参见Why is GetFileAttributes the way old-timers test file existence?

或者,您根本无法在打开文件之前根本不检查文件是否存在,只是无条件打开它并捕获所产生的错误。操作系统会告诉您失败是由于找不到文件还是其他错误导致的。