是否有标准函数在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\')
Run Code Online (Sandbox Code Playgroud)
phi*_*ext 48
要转换为绝对你有:
ExpandFileName
拥有相对路径:
ExtractRelativePath
And*_*and 34
我将使用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;
Run Code Online (Sandbox Code Playgroud)
当然,如果使用非Unicode版本的Delphi(即<= Delphi 2007),则需要使用Ansi函数(*A)而不是Unicode函数(*W).
Dav*_*nan 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;
Run Code Online (Sandbox Code Playgroud)
您需要将该ShLwApi装置用于PathIsRelative和PathCanonicalize.
调用PathIsRelative意味着例程对指定的绝对路径是健壮的.
所以,SysUtils.ExtractRelativePath可以将您AbsToRel唯一的参数反转.而我的ExpandFileNameRelBaseDir意志将成为你的RelToAbs.
我只是一起酿造:
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;
Run Code Online (Sandbox Code Playgroud)
感谢Andreas和David引起我对Shell Path Handling Functions的注意.