delphi 合并(“c:,”“myfile.txt”)忽略了目录分隔符

8e2ybdfx  于 2022-11-23  发布在  其他
关注(0)|答案(4)|浏览(101)

所以当我跑的时候

TPath.Combine('c:', 'myfile.txt');

在 Delphi XE2中,我会得到“C:myfile.txt”作为返回。这不是我所期望的,在Windows中它不是一个有效的路径。我希望合并是对Windows API(http://msdn.microsoft.com/en-us/library/fyy7a5kt%28v=vs.110%29.aspx)的调用,或者具有与API相同的行为。
我做错了什么吗?我能“修复”合并的行为吗?还是我必须搜索代码中的所有用法,并用一个字符串连接替换它,中间有一个''?

prdp8dxp

prdp8dxp1#

我认为这种行为是正确的,并且符合设计。C:myfile.txtC:\myfile.txt之间存在差异。Windows文档非常明确地指出了这一点:
如果文件名仅以磁盘指示符开头,而不是冒号后的反斜杠,则它将被解释为驱动器上具有指定字母的当前目录的相对路径。请注意,当前目录可能是根目录,也可能不是根目录,这取决于在该磁盘上最近一次“更改目录”操作期间的设置。此格式的示例如下:

  • “C:tmp.txt”是指驱动器C上当前目录中名为“tmp.txt”的文件。
  • “C:tempdir\tmp.txt”引用驱动器C上当前目录的子目录中的文件。

如果RTL函数TPath.Combine在驱动器标志符后添加了一个分隔符,那么你就无法使用TPath.Combine来生成类似"C:tmp.txt"的路径。因此,如果你想要一个目录分隔符,你需要自己提供一个:

TPath.Combine('c:\', 'myfile.txt');

注意.net framework方法Path.Combine( Delphi RTL类TPath在其上松散建模)的行为与Delphi RTL等价物相同。

相关:

lfapxunr

lfapxunr2#

当合并文件夹名称和文件夹文件时,最好通过IncludeTrailingPathDelimiter方法来放置文件夹名称(如果您不希望在驱动器标识符作为路径时使用默认行为)。如果路径中没有尾随分隔符,该方法会在路径中添加尾随分隔符

TPath.Combine(IncludeTrailingPathDelimiter('c:'), 'myfile.txt');
w51jfk4q

w51jfk4q3#

合并和CombinePath函数在路径名过长的情况下会出现问题,而且当路径实际上不在驱动器上时(例如在zip文件中),它也不起作用。

function ExpandFileNameEx(const BasePath, RelativeFileName: string): string;
var
  p:integer;
  s,folder:string;
begin
  { Check if Relative file name is a fully qualified path: }
  if (pos(':\', RelativeFileName) > 0) or (copy(RelativeFileName,1,2) = '\\') then
    Result := RelativeFileName

  { Check if Relative file name is a root path assignment: }
  else if copy(RelativeFileName,1,1) = '\' then
  begin
    Result := IncludeTrailingPathDelimiter(ExtractFileDrive(BasePath))
             + Copy(RelativeFileName,2,Length(RelativeFileName));
  end else
  begin
    { Check all sub paths in Relative file name: }
    Result := BasePath;
    s := RelativeFileName;
    repeat
      p := pos('\', s);
      if p > 0 then
      begin
        folder := Copy(s,1,p-1);
        Delete(s, 1,p);
      end else
      begin
        folder := s;
        s := '';
      end;

      if folder <> EmptyStr then
      begin
        if Folder = '..' then
          Result := ExtractFileDir(Result)
        else if Folder = '.' then
          { No action }
        else
          Result := IncludeTrailingPathDelimiter(Result) + Folder;
      end;
    until p = 0;
  end;
end;
vqlkdk9b

vqlkdk9b4#

这就是为什么你应该总是使用IncludeTrailingBackslash(或者IncludeTrailingPathDelimiter,如果你是受虐狂的话):

*之前TPath.Combine('c:', 'myfile.txt');
*之后IncludeTrailingBackslash('c:')+'myfile.txt';

它避免了其他人在设计their abstraction.时所考虑的未知的细微差别,或者他们没有费心去处理的边缘情况,或者他们没有费心去记录的怪癖

相关问题