Win32 CreateDirectory因长路径而失败

问题描述 投票:0回答:2

环境是Windows 7 Pro和Delphi 7。

Windows.CreateDirectory()无法创建非常长的路径,该路径远低于路径长度限制。 GetLastError为ERROR_PATH_NOT_FOUND。

该故障在ESXi虚拟机,本机Win7工作站和物理磁盘上相同。 Windows.MoveFile也会发生类似的故障。

下面的代码中的长路径已在CMD窗口中正确创建,作为粘贴到MKDIR的参数。我的变通办法是创建此漫长的零碎餐。我将“ \”字符处的路径拆分为一个字符串数组。然后,我循环数组并从每个元素构建累积路径。循环正确地构建了完整路径而没有错误。

我不知道为什么Win32函数无法创建有效的长路径。

var
arrDstPath : TStringArray;

begin
// --------------
// failing method
// --------------
strDstPath := 'C:\Duplicate Files\my customer recovered data\desktop\my customer name\application data\gtek\gtupdate\aupdate\channels\ch_u3\html\images\';

if (Windows.CreateDirectory(pchar(strDstPath),nil) = false) then
    result := Windows.GetLastError;  // #3 is returned
if (DirectoryExists(strNewPath) = false) then
    result := ERROR_PATH_NOT_FOUND;

// -----------------
// successful method
// -----------------
strNewPath := '';
LibSplitToArray(arrDstPath,'\',strDstPath);
for intIdx := 0 to High(arrDstPath) do
    begin
    strNewPath := strNewPath + arrDstPath[intIdx] + '\';
    Windows.CreateDirectory(pchar(strNewPath),nil);
    end;

if (DirectoryExists(strDstPath) = false) then       // compare to original path string
    begin
    result := ERROR_PATH_NOT_FOUND;
    exit;
    end;
delphi create-directory
2个回答
0
投票

这是因为CreateDirectory无法递归创建目录。

为此,从Delphi 2007(甚至更早)开始,SysUtils就具有函数ForceDirectories

function ForceDirectories(Dir: string): Boolean;
var
  E: EInOutError;
begin
  Result := True;
  if Dir = '' then
  begin
    E := EInOutError.CreateRes(@SCannotCreateDir);
    E.ErrorCode := 3;
    raise E;
  end;
  Dir := ExcludeTrailingPathDelimiter(Dir);
{$IFDEF MSWINDOWS}
  if (Length(Dir) < 3) or DirectoryExists(Dir)
    or (ExtractFilePath(Dir) = Dir) then Exit; // avoid 'xyz:\' problem.
{$ENDIF}
{$IFDEF LINUX}
  if (Dir = '') or DirectoryExists(Dir) then Exit;
{$ENDIF}
  Result := ForceDirectories(ExtractFilePath(Dir)) and CreateDir(Dir);
end;

0
投票

实际上,CreateDirectory函数的官方文档描述了正在发生的事情。由于该函数失败,因此您的直觉应该是查看描述返回值的部分,该部分指出:

ERROR_ALREADY_EXISTS

指定的目录已经存在。

ERROR_PATH_NOT_FOUND

一个或多个中间目录不存在;此函数只会在路径中创建最终目录。

[我假设您得到了CreateDirectory,并且该文档提出了一个可能的原因:您试图一次创建该功能不支持的多个级别的子目录。

幸运的是,Delphi RTL具有ERROR_PATH_NOT_FOUND函数,可以递归创建子目录。 (ForceDirectories)。

在Delphi 2010及更高版本中,您也可以使用ForceDirectories中的How can I Create folders recursively in Delphi?。在内部,此调用TDirectory.CreateDirectory

© www.soinside.com 2019 - 2024. All rights reserved.