urls una rutas ruta relativos relativas relativa quƩ obtener archivo acceso absolutos absolutas absoluta delphi path

delphi - una - url relativos y absolutos



ConversiĆ³n entre rutas absolutas y relativas en Delphi (9)

¿Hay funciones estándar para realizar la conversión de ruta relativa absoluta <-> en Delphi?

Por ejemplo:

  • La ruta ''Base'' es ''C:/Projects/Project1/'
  • La ruta relativa es ''../Shared/somefile.pas''
  • La ruta absoluta es ''C:/Projects/Shared/somefile.pas''

Estoy buscando algo como esto:

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/')


Acabo de elaborar esto juntos:

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;

Gracias a Andreas y David por llamar mi atención sobre las funciones de manejo de la ruta de Shell .


Compruebe si su solución funcionará con la ruta relativa a la ruta completa en caso de que cambie el directorio actual. Esto funcionará:

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;


No estoy muy seguro de si esto todavía es necesario después de más de 2 años, pero aquí hay una manera de hacer que el Relativo sea Absoluto (En cuanto a Absoluto a Relativo sugeriría la respuesta ExtractRelativePath ):

Unidad: IOUtils

Padre: TPath

function GetFullPath(const BasePath: string): string;

Devolverá la ruta completa y absoluta para una ruta relativa dada. Si la ruta dada ya es absoluta, simplemente la devolverá tal como está.

Aquí está el enlace en Embarcadero: Get Full Path

Y aquí hay un enlace para Rutinas de Manipulación de Caminos


Otra versión de RelToAbs (compatible con todas las versiones de 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;


Para convertir a lo absoluto tienes:

ExpandFileName

Para tener la ruta relativa que tiene:

ExtractRelativePath


Por lo que vale, mi base de código usa SysUtils.ExtractRelativePath en una dirección y regresa la siguiente envoltura local:

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;

Tendrá que usar la unidad PathIsRelative para PathIsRelative y PathCanonicalize .

La llamada a PathIsRelative significa que la rutina es robusta para las rutas absolutas que se especifican.

Entonces, SysUtils.ExtractRelativePath puede ser su AbsToRel solo los parámetros están invertidos. Y mi ExpandFileNameRelBaseDir servirá como tus RelToAbs .


Una solución alternativa para RelToAbs es simplemente:

ExpandFileName(IncludeTrailingPathDelimiter(BasePath) + RelPath)


Utilizaría PathRelativePathTo como la primera función y PathCanonicalize como el segundo. En el último caso, como argumento, pasa la suma de cadena de la ruta base y la ruta relativa.

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;

Por supuesto, si utiliza una versión de Delphi que no es Unicode (es decir, <= Delphi 2007), debe usar las funciones Ansi ( *A ) en lugar de las funciones Unicode ( *W ).


TPath.Combine(S1, S2);

Debería estar disponible desde Delphi XE.