所以当我跑
时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的行为?或者我是否必须在我的代码中搜索所有用途,并将其替换为字符串连接与' \'介于两者之间?
答案 0 :(得分:8)
我认为行为是正确的,并且按照设计。 C:myfile.txt
和C:\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. 时所考虑的未知细微差别,或者他们不愿意处理的边缘情况,或者他们不愿意记录的怪癖