是否有执行绝对的标准功能< - > Delphi中的相对路径转换?
例如:
'C:\Projects\Project1\'
'..\Shared\somefile.pas'
'C:\Projects\Shared\somefile.pas'
我正在寻找类似的东西:
function AbsToRel(const AbsPath, BasePath: string): string;
// '..\Shared\somefile.pas' =
// AbsToRel('C:\Projects\Shared\somefile.pas', 'C:\Projects\Project1\')
function RelToAbs(const RelPath, BasePath: string): string;
// 'C:\Projects\Shared\somefile.pas' =
// RelToAbs('..\Shared\somefile.pas', 'C:\Projects\Project1\')
答案 0 :(得分:47)
要转换为您拥有的绝对值:
ExpandFileName
拥有相对路径:
ExtractRelativePath
答案 1 :(得分:33)
我会使用PathRelativePathTo
作为第一个函数,PathCanonicalize
作为第二个函数。在后一种情况下,作为参数传递基本路径和相对路径的字符串和。
function PathRelativePathTo(pszPath: PChar; pszFrom: PChar; dwAttrFrom: DWORD;
pszTo: PChar; dwAtrTo: DWORD): LongBool; stdcall; external 'shlwapi.dll' name 'PathRelativePathToW';
function AbsToRel(const AbsPath, BasePath: string): string;
var
Path: array[0..MAX_PATH-1] of char;
begin
PathRelativePathTo(@Path[0], PChar(BasePath), FILE_ATTRIBUTE_DIRECTORY, PChar(AbsPath), 0);
result := Path;
end;
function PathCanonicalize(lpszDst: PChar; lpszSrc: PChar): LongBool; stdcall;
external 'shlwapi.dll' name 'PathCanonicalizeW';
function RelToAbs(const RelPath, BasePath: string): string;
var
Dst: array[0..MAX_PATH-1] of char;
begin
PathCanonicalize(@Dst[0], PChar(IncludeTrailingBackslash(BasePath) + RelPath));
result := Dst;
end;
procedure TForm4.FormCreate(Sender: TObject);
begin
ShowMessage(AbsToRel('C:\Users\Andreas Rejbrand\Desktop\file.txt', 'C:\Users\Andreas Rejbrand\Pictures'));
ShowMessage(RelToAbs('..\Videos\movie.wma', 'C:\Users\Andreas Rejbrand\Desktop'));
end;
当然,如果您使用非Unicode版本的Delphi(即< = Delphi 2007),则需要使用Ansi函数(*A
)而不是Unicode函数({{1 }})。
答案 2 :(得分:12)
对于它的价值,我的代码库在一个方向上使用SysUtils.ExtractRelativePath
并且以下的本土包装器会回来:
function ExpandFileNameRelBaseDir(const FileName, BaseDir: string): string;
var
Buffer: array [0..MAX_PATH-1] of Char;
begin
if PathIsRelative(PChar(FileName)) then begin
Result := IncludeTrailingBackslash(BaseDir)+FileName;
end else begin
Result := FileName;
end;
if PathCanonicalize(@Buffer[0], PChar(Result)) then begin
Result := Buffer;
end;
end;
您需要将ShLwApi
单位用于PathIsRelative
和PathCanonicalize
。
对PathIsRelative
的调用意味着该例程对于指定的绝对路径是健壮的。
因此,SysUtils.ExtractRelativePath
可以是您的AbsToRel
只有参数被反转。我的ExpandFileNameRelBaseDir
将作为您的RelToAbs
。
答案 3 :(得分:5)
我只是一起酿造:
uses
ShLwApi;
function RelToAbs(const ARelPath, ABasePath: string): string;
begin
SetLength(Result, MAX_PATH);
if PathCombine(@Result[1], PChar(IncludeTrailingPathDelimiter(ABasePath)), PChar(ARelPath)) = nil then
Result := ''
else
SetLength(Result, StrLen(@Result[1]));
end;
感谢Andreas和David引起我对Shell Path Handling Functions的注意。
答案 4 :(得分:2)
TPath.Combine(S1, S2);
自Delphi XE以来应该可用。
答案 5 :(得分:1)
RelToAbs
的替代解决方案很简单:
ExpandFileName(IncludeTrailingPathDelimiter(BasePath) + RelPath)
答案 6 :(得分:1)
如果您更改当前目录,请检查您的解决方案是否适用于相对路径到完整路径。这将有效:
function PathRelativeToFull(APath : string) : string;
var
xDir : string;
begin
xDir := GetCurrentDir;
try
SetCurrentDir('C:\Projects\Project1\');
Result := ExpandFileName(APath);
finally
SetCurrentDir(xDir);
end{try..finally};
end;
function PathFullToRelative(APath : string; ABaseDir : string = '') : string;
begin
if ABaseDir = '' then
ABaseDir := 'C:\Projects\Project1\';
Result := ExtractRelativePath(ABaseDir, APath);
end;
答案 7 :(得分:0)
我不太确定2年以后是否还需要这个,但这里有一种方法可以让相对于绝对(至于绝对相对我会建议philnext' s {{ 1}}回答):
单位:IOUtils
父母:TPath
ExtractRelativePath
它将返回给定相对路径的完整绝对路径。如果给定路径已经是绝对路径,它将按原样返回。
以下是Embarcadero的链接:Get Full Path
的链接答案 8 :(得分:0)
RelToAbs的另一个版本(与所有Delphi XE版本兼容)。
Node.childNodes