c# - getfilename - ¿Cómo hacer una ruta absoluta relativa a una carpeta en particular?
paths in c# (4)
¿Por qué todas esas soluciones complicadas?
¿Y con la participación de Uri? De Verdad ? No tendrá que esperar mucho tiempo para la primera excepción.
Hay brillantez en la simplicidad.
No hay necesidad de ninguna clase marco adicional.
public static string BuildRelativePath(string absolutePath, string basePath)
{
return absolutePath.Substring(basePath.Length);
}
Y en caso de que no pueda administrar agregar u omitir siempre el System.IO.Path.DirectorySeparatorChar de cierre en sus cadenas, o no pueda mezclar los argumentos:
public static string FaultTolerantRelativePath(string absolutePath, string basePath)
{
if(absolutePath == null || basePath == null)
return null;
absolutePath = absolutePath.Replace(System.IO.Path.DirectorySeparatorChar, ''/'');
basePath = basePath.Replace(System.IO.Path.DirectorySeparatorChar, ''/'');
if (!basePath.EndsWith("/"))
basePath += "/";
if (!absolutePath.EndsWith("/"))
absolutePath += "/";
if (absolutePath.Length < basePath.Length)
throw new ArgumentException("absolutePath.Length < basePath.Length ? This can''t be. You mixed up absolute and base path.");
string resultingPath = absolutePath.Substring(basePath.Length);
resultingPath = resultingPath.Replace(''/'', System.IO.Path.DirectorySeparatorChar);
return resultingPath;
}
Por ejemplo, ¿cómo puedo hacer esto?
"C:/RootFolder/SubFolder/MoreSubFolder/LastFolder/SomeFile.txt"
relativo a esta carpeta
"C:/RootFolder/SubFolder/"
si el resultado esperado es
"MoreSubFolder/LastFolder/SomeFile.txt"
Aquí están mis 5 centavos sin usar ninguna clase especial de URL para ese propósito.
Busque makeRelative en el siguiente repositorio svn:
https://sourceforge.net/p/syncproj/code/HEAD/tree/syncProj.cs#l976
Arreglaré errores si hay alguno.
En su ejemplo, es simplemente absPath.Substring(relativeTo.Length)
.
Un ejemplo más elaborado requeriría retroceder algunos niveles de la relativeTo
, de la siguiente manera:
"C:/RootFolder/SubFolder/MoreSubFolder/LastFolder/SomeFile.txt"
"C:/RootFolder/SubFolder/Sibling/Child/"
El algoritmo para hacer una ruta relativa se vería como sigue:
- Elimine el prefijo común más largo (en este caso, es
"C:/RootFolder/SubFolder/"
) - Cuente el número de carpetas en
relativeTo
(en este caso, es 2:"Sibling/Child/"
) - Insertar
../
para cada carpeta restante - Concatene con el resto de la ruta absoluta después de la eliminación del sufijo
El resultado final se ve así:
"../../MoreSubFolder/LastFolder/SomeFile.txt"
Sí, puedes hacer eso, es fácil, piensa en tus caminos como URI :
Uri fullPath = new Uri(@"C:/RootFolder/SubFolder/MoreSubFolder/LastFolder/SomeFile.txt", UriKind.Absolute);
Uri relRoot = new Uri(@"C:/RootFolder/SubFolder/", UriKind.Absolute);
string relPath = relRoot.MakeRelativeUri(fullPath).ToString();
// relPath == @"MoreSubFolder/LastFolder/SomeFile.txt"