Delphi中绝对路径与相对路径的转换
Delphi中是否有执行绝对相对路径转换的标准函数 例如:Delphi中绝对路径与相对路径的转换,delphi,path,Delphi,Path,Delphi中是否有执行绝对相对路径转换的标准函数 例如: “基本”路径是'C:\Projects\Project1\' 相对路径是“”..\Shared\somefile.pas” 绝对路径是'C:\Projects\Shared\somefile.pas' 我在找这样的东西: function AbsToRel(const AbsPath, BasePath: string): string; // '..\Shared\somefile.pas' = // AbsToRel('C:
- “基本”路径是
'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\')
我将用作第一个函数和第二个函数。在后一种情况下,作为参数传递基本路径和相对路径的字符串和
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(即,转换为绝对值): 扩展文件名 要获得您拥有的相对路径,请执行以下操作: 相对提取器
值得一提的是,我的代码库在一个方向上使用了
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;
对于PathIsRelative
和pathcononicalize
,您需要使用ShLwApi
单元
对PathIsRelative
的调用意味着例程对指定的绝对路径具有鲁棒性
因此,
SysUtils.ExtractRelativePath
可以作为您的Absorel
只有参数是反向的。而我的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;
感谢Andreas和David提醒我注意。我不太确定2年多后是否还需要这样做,但这里有一种方法可以获得相对到绝对(至于绝对到相对,我建议的
提取相对路径
答案):
单位:IOUtils
家长:TPath
function GetFullPath(const BasePath: string): string;
它将返回给定相对路径的完整绝对路径。如果给定路径已经是绝对路径,它将按原样返回
以下是Embarcadero的链接:
这里有一个链接关于
reltoab
的另一个解决方案是:
ExpandFileName(IncludeTrailingPathDelimiter(BasePath) + RelPath)
应在Delphi XE之后可用。检查您的解决方案是否可以在更改当前目录时使用相对路径到完整路径。这将起作用:
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;
RelToAbs的另一个版本(与所有Delphi XE版本兼容)
@安德烈亚斯:是的,但它需要一些工作来适应这个问题。ExpandFileName在这里不好。它使用的是工作目录,而不是用户指定的目录。您将需要类似安德烈亚斯的答案或我自己的答案。尽管作为一个补充,如果您像我一样想解析/data/whater/parent/child//到/data/whater/parent/child-这个ExpandFileName非常有用,而且是跨平台的。无需声明PathCanonicalize,只需将其从ShLwApi@David:是的,我现在明白了。请注意,只有当RelPath真的是一个相对路径时,RelToAbs才有效。如果它是一个绝对路径,那么它将失败。在实际应用中,最好有一个at对此很有弹性,因为通常您允许用户指定绝对或相对路径。我假设
TWin32PathBuffer
是数组[0..MAX\u PATH-1]关于char
?@Andreas正确,谢谢。从代码中挑出一些片段,然后使其独立起来总是很有趣的。我是一个upvoter,不是downvoter,除了你的评论中的一个输入错误之外,我没有看到任何错误:*他们没有,也许@downvoter给了你-1,因为你没有指定什么模块(Windows
,ShLwApi
)是编译示例所必需的“最佳”答案也没有指定。还有一件事:变量s
已声明但未使用。是绝对路径“C:\Projects\Shared\somefile.pas”或“C:\Projects\Project1\Shared\somefile.pas”?@philnext它是C:\Projects\Shared\somefile.pas
。指示一个文件夹,该文件夹将从基本(或根)路径。
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;
uses
ShLwApi;
function RelPathToAbsPath(const ARelPath, ABasePath: string): string;
var Buff:array[0..MAX_PATH] of Char;
begin
if PathCombine(Buff, PChar(IncludeTrailingPathDelimiter(ABasePath)), PChar(ARelPath)) = nil then
Result := ''
else Result:=Buff;
end;