FileExists returns true 但文件不存在
FileExists returns true but file doesn't exist
我在 Delphi 7 中编写我的程序。我只需要它处理非 Unicode 文件名。如果它找到一个 Unicode 文件名,它应该忽略它。
我的代码如下所示:
var Filename: String;
if not FileExists(Filename) then Exit;
F := TFileStream(Filename, fmOpenRead or fmShareDenyWrite);
然而,对于某些 Unicode 文件名,FileExists() returns 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 来获得正确的结果?
不是 TFileStream
本身,不是。但是您可以改用 Win32 CreateFileW()
to open the Unicode filename, and then assign the returned HANDLE
to a THandleStream
。这基本上就是 TFileStream
内部所做的(在 Delphi 7 中使用 CreateFileA()
)。
Delphi 的更高版本在其实现中使用 Win32 GetFileAttributes()
1 而不是 RTL 的 FileAge()
FileExists()
。 GetFileAttributes()
不支持通配符,而 FindFirstFile()
支持。
1. 参见 Why is GetFileAttributes the way old-timers test file existence?
或者,您可以在打开文件之前根本不检查文件是否存在,只是无条件地打开它并捕获由此产生的错误。 OS 会告诉您失败是由于找不到文件还是其他错误。
我在 Delphi 7 中编写我的程序。我只需要它处理非 Unicode 文件名。如果它找到一个 Unicode 文件名,它应该忽略它。
我的代码如下所示:
var Filename: String;
if not FileExists(Filename) then Exit;
F := TFileStream(Filename, fmOpenRead or fmShareDenyWrite);
然而,对于某些 Unicode 文件名,FileExists() returns 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 来获得正确的结果?
不是
TFileStream
本身,不是。但是您可以改用 Win32CreateFileW()
to open the Unicode filename, and then assign the returnedHANDLE
to aTHandleStream
。这基本上就是TFileStream
内部所做的(在 Delphi 7 中使用CreateFileA()
)。Delphi 的更高版本在其实现中使用 Win32
GetFileAttributes()
1 而不是 RTL 的FileAge()
FileExists()
。GetFileAttributes()
不支持通配符,而FindFirstFile()
支持。1. 参见 Why is GetFileAttributes the way old-timers test file existence?
或者,您可以在打开文件之前根本不检查文件是否存在,只是无条件地打开它并捕获由此产生的错误。 OS 会告诉您失败是由于找不到文件还是其他错误。