Delphi Tpath.Combine(' c:',' myfile.txt')省略了DirSeperator

时间:2014-09-04 15:53:45

标签: delphi path delphi-xe2

所以当我跑

TPath.Combine('c:', 'myfile.txt');
在Delphi XE2中,我得到了C:myfile.txt'作为回报。这不是我所期望的,它不是Windows中的有效路径。我希望TPath.Combine能够调用windows API(http://msdn.microsoft.com/en-us/library/fyy7a5kt%28v=vs.110%29.aspx)或者具有与API相同的行为。

我做错了吗?我可以修复" TPath.Combine的行为?或者我是否必须在我的代码中搜索所有用途,并将其替换为字符串连接与' \'介于两者之间?

4 个答案:

答案 0 :(得分:8)

我认为行为是正确的,并且按照设计。 C:myfile.txtC:\myfile.txt之间存在差异。 Windows documentation非常明确地称呼它:

  

如果文件名仅以磁盘指示符开头而不是   冒号后的反斜杠,它被解释为相对路径   具有指定字母的驱动器上的当前目录。注意   当前目录可能是也可能不是根目录   在最近的"更改目录"中设置的内容   该磁盘上的操作。此格式的示例如下:

     
      
  • " C:tmp.txt"是指一个名为" tmp.txt"的文件。在驱动器C上的当前目录中。
  •   
  • " C:TEMPDIR \ tmp.txt"指的是驱动器C上当前目录的子目录中的文件。
  •   

如果RTL函数TPath.Combine在驱动器指示符之后添加了分隔符,则无法使用TPath.Combine生成类似"C:tmp.txt"的路径。所以,如果你想要一个目录分隔符,你需要自己提供一个:

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

请注意,对Delphi RTL类Path.Combine进行松散建模的.net框架方法TPath的行为与Delphi RTL相同。

相关:

答案 1 :(得分:0)

组合文件夹名称和文件夹文件时,最好通过IncludeTrailingPathDelimiter方法放置filder名称。如果没有一个

,此方法将为您的路径添加尾随分隔符
TPath.Combine(IncludeTrailingPathDelimiter('c:'), 'myfile.txt');

答案 2 :(得分:0)

Path.Combine和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;

答案 3 :(得分:0)

这就是为什么您应该始终使用 IncludeTrailingBackslash(如果您是受虐狂,则应使用 IncludeTrailingPathDelimiter):

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

它避免了其他人在设计 their abstraction. 时所考虑的未知细微差别,或者他们不愿意处理的边缘情况,或者他们不愿意记录的怪癖update component