Преобразование между абсолютными и относительными путями в Delphi

Существуют ли стандартные функции для выполнения абсолютного относительного преобразования пути в Delphi?

Например:

  • «Base» – это '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\') 

Я бы использовал 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; 

Конечно, если вы используете версию Delphi, отличную от Unicode (то есть <= Delphi 2007), вам нужно использовать функции Ansi ( *A ) вместо функций Unicode ( *W ).

Чтобы преобразовать в абсолют, вы имеете:

ExpandFileName

Чтобы иметь относительный путь, который у вас есть:

ExtractRelativePath

Для чего это стоит, моя кодовая база использует 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 для 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; 

Спасибо Андреасу и Дэвиду за то, что привлекли мое внимание к функциям обработки пути Shell .

 TPath.Combine(S1, S2); 

Должно быть доступно с Delphi XE.

Альтернативное решение для RelToAbs просто:

 ExpandFileName(IncludeTrailingPathDelimiter(BasePath) + RelPath) 

Проверьте, будет ли ваше решение работать с Relative Path To Full Path в случае, если вы меняете текущий каталог. Это будет работать:

 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; 

Я не слишком уверен, что это все еще необходимо после 2+ лет, но вот способ получить Относительное к Абсолюту (Что касается Абсолютного Относительного, я бы предложил ответ ExtractRelativePath ):

Единица измерения: IOUtils

Родитель: TPath

 function GetFullPath(const BasePath: string): string; 

Он вернет полный, абсолютный путь для данного относительного пути. Если данный путь уже является абсолютным, он просто вернет его как есть.

Вот ссылка на Embarcadero: Получить полный путь

И вот ссылка для процедур манипуляции с путями

Другая версия RelToAbs (совместимая со всеми версиями Delphi XE).

 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; 
  • Перемещение файла app.config на пользовательский путь
  • Как объединить пути в Java?
  • Найти имя файла из полного пути к файлу
  • Конкатенация строк в Less
  • Такой же абсолютный путь на linux и windows 7
  • Java 7: путь к файлу
  • Где $ PATH устанавливается в OS X 10.6 Snow Leopard?
  • Список всех файлов, соответствующих шаблону полного пути в R
  • Что такое PATH и другие переменные среды, и как я могу их установить или использовать?
  • Возможные проблемы с добавлением / usr / local / bin к корневому пути?
  • Избегайте нежелательного пути в Zip-файле
  • Давайте будем гением компьютера.