在delphi XE中,当我使用以下输入调用SysUtils DirectoryExists函数时
'Y:\布拉布拉\'
其中Y是网络映射单元,它正确返回false,因为blabla不存在。
但是当我使用以下输入调用时
'Y:\布拉布拉\ Y:\ BLA'
它返回true。
文档很差,而且我没有在具有相同问题的互联网上找到任何人
也许这里有人已经遇到过这个问题,或者知道发生了什么事?
答案 0 :(得分:5)
这似乎是DirectoryExists函数实现中的一个错误。
这是此功能的相关代码
function DirectoryExists(const Directory: string; FollowLink: Boolean = True): Boolean;
{$IFDEF MSWINDOWS}
var
Code: Cardinal;
Handle: THandle;
LastError: Cardinal;
begin
Result := False;
Code := GetFileAttributes(PChar(Directory));
if Code <> INVALID_FILE_ATTRIBUTES then
begin
...
//more code
...
end
else
begin
LastError := GetLastError;
Result := (LastError <> ERROR_FILE_NOT_FOUND) and
(LastError <> ERROR_PATH_NOT_FOUND) and
(LastError <> ERROR_INVALID_NAME) and
(LastError <> ERROR_BAD_NETPATH);
end;
end;
{$ENDIF MSWINDOWS}
当您看到GetFileAttributes
函数调用失败时,GetLastError
方法的结果将与一组可能的值进行比较。但在您的情况下,传递无效路径将返回ERROR_BAD_PATHNAME
(161)代码,因此该函数返回True。
答案 1 :(得分:0)
该错误仍然存在于XE8中(也可能在其他版本中)。正如上面RRUZ所指出的那样,它位于 BOTH DirectoryExists() 和 TDirectory.Exists()的SysUtils实现中。 强>
问题在于长长的&#34;检查&#34;假设它们是唯一有效的原因,可能已经在&#34;存在&#34;的上下文中返回了INVALID_FILE_ATTRIBUTES。的文件夹。但我们称之为这些例程的原因是几乎总是,因此我们可以检查我们是否可以 使用 我们要询问的文件夹。拥有INVALID_FILE_ATTRIBUTES几乎总是意味着我们不能。无论哪种方式,目前正在进行的测试都不会产生明显的结果。这个事实本身就是一个完全冗余的练习,因为它允许某些其他故障代码在网络中滑动并且在不应该的时候将最终结果设置为TRUE。虽然我只能想象这种疯狂最初有一些方法,但是,它存在但可能无效&#34;,它违背了未来可能带来更多代码的固有事实由许多尚未知的文件系统和/或硬件生成:所以底线是99.9%的使用率,获取 INVALID_FILE_ATTRIBUTES 应该意味着文件夹不可用,它是因此,一旦已经建立,就允许返回TRUE,这是不合逻辑的。
不幸的是,我们无法知道是否存在依赖于当前行为的代码来识别带有问题的现有路径&#34; - 在这种情况下,对当前存在的例程的调用必须先进行路径语法验证检查:否则会说用语法错误描述的路径&#34;存在&#34;,这是一个废话!之后您无法重做 GetLastError ,因为错误已经被清除。
所以唯一的办法是包装任何 Sysutils.DirectoryExists 和(不幸的是) TDirectory.Exists 调用代码可以预先消除问题。例如:
DirectoryUsable(const Directory: string; FollowLink: Boolean = True): Boolean;
begin
Result := GetFileAttributes(PChar(Directory)) <> INVALID_FILE_ATTRIBUTES;
if Result then Result := DirectoryExists( Directory, FollowLink );
end;
或者,或者你对所有&#34;坏&#34;进行单独的预先验证。你知道的情况和Embarcadero错过了 - 即和他们一样玩同样的失败游戏。 可怕,但你去了。
您也可以自己修改SysUtils库,添加缺少的案例,对于您遇到的每个新案例,您必须为每个版本的Delphi 和重做。如果Embarcadero终于&#34;咬紧牙关&#34;那可能会更好。并找到解决此问题的更好方法。也许通过使用另一个默认的标志参数,该参数表示&#34;拒绝所有无效目录&#34;。我会进一步建议默认为TRUE。