2010-07-08 61 views
26

que tienen una ruta absoluta para presentar A.Conversión de rutas relativas a rutas absolutas

tengo una ruta relativa al archivo B del directorio de archivos de una. Esta ruta puede usar y usará "..." para subir la estructura de directorios en formas arbitrariamente complejas.

Ejemplo A:

  • C:\projects\project1\module7\submodule5\fileA

Ejemplo B:

  • ..\..\module3\submodule9\subsubmodule32\fileB
  • ..\submodule5\fileB
  • ..\..\module7\..\module4\submodule1\fileB
  • fileB

¿Cómo combinar los dos con el fin de obtener la posible ruta absoluta más sencilla de presentar B?

+0

** tl; dr respuesta:. ** nuevo archivo ("mi/ruta") getCanonicalPath() – Andrew

Respuesta

36

Si consigo su derecha problema, se podría hacer algo como esto:

File a = new File("/some/abs/path"); 
File parentFolder = new File(a.getParent()); 
File b = new File(parentFolder, "../some/relative/path"); 
String absolute = b.getCanonicalPath(); // may throw IOException 
+1

Pero la ruta absoluta pueden tener .. está en eso si hago eso. Yo no los quiero. ¿Hay alguna manera de deshacerse de ellos del camino absoluto resultante? –

+9

@Tom: Usar 'getCanonicalPath()' en lugar de 'getAbsolutePath()' es probablemente lo que estás buscando, en ese caso. –

+0

@Tim Gracias, actualizó la respuesta. –

0

Sé que no es la mejor solución, pero no puedes combinar la subcadena de la trayectoria de archivoA desde 0 hasta el lastIndexOf("\") con la ruta del archivoB.

Ejemplo A:

  • C:\projects\project1\module7\submodule5\fileA

Ejemplo B:

  • ..\..\module3\submodule9\subsubmodule32\fileB

C:\projects\project1\module7\submodule5\..\..\module3\submodule9\subsubmodule32\fileB

Si no quiere el .. allí, tomaría más tiempo, pero le recomiendo ir por la ruta de fileB y seguir tomando la subcadena de 0 al primer índice de \. Luego revisa la subcadena. Si es .., elimine la subcadena de allí y elimine la subcadena de la ruta fileA's de lastIndexOf(\) a la longitud. Entonces repite. De esta forma, eliminará las carpetas que no necesita y el ..s.

Así:

Ejemplo A:

  • C:\projects\project1\module7\submodule5\fileA

Ejemplo B:

  • ..\..\module3\submodule9\subsubmodule32\fileB

    ->C:\projects\project1\module3\submodule9\subsubmodule32\fileB

+0

Debo aclarar, quiero la forma más simple de la ruta a B. –

0

Aquí es el código de ejemplo que funciona para mí.

public String absolutePath(String relative, String absoluteTo) 
    {  
     String[] absoluteDirectories = relative.split("\\\\"); 
     String[] relativeDirectories = absoluteTo.split("\\\\"); 
     int relativeLength = relativeDirectories.length; 
     int absoluteLength = absoluteDirectories.length; 
     int lastCommonRoot = 0; 
     int index; 
     for (index = 0; index < relativeLength; index++) 
      if (relativeDirectories[index].equals("..\\\\")) 
       lastCommonRoot = index; 
      else 
       break; 
     StringBuilder absolutePath = new StringBuilder(); 
     for (index = 0; index < absoluteLength - lastCommonRoot; index++) 
     { 
      if (absoluteDirectories[index].length() > 0) 
       absolutePath.append(absoluteDirectories[index] + "\\\\");       
     } 
     for (index = lastCommonRoot; index < relativeLength - lastCommonRoot; 
                   index++) 
     { 
      if (relativeDirectories[index].length() > 0) 
       absolutePath.append(relativeDirectories[index] + "\\\\");       
     } 
     return absolutePath.toString();    
    } 

también que la conversión al respecto:

public String relativePath(String absolute, String relativeTo) throws Exception 
    {  
     String[] absoluteDirectories = absolute.split("\\\\"); 
     String[] relativeDirectories = relativeTo.split("\\\\"); 
     int length = absoluteDirectories.length < relativeDirectories.length ? 
         absoluteDirectories.length : relativeDirectories.length; 
     int lastCommonRoot = -1; 
     int index; 
     for (index = 0; index < length; index++) 
      if (absoluteDirectories[index].equals(relativeDirectories[index])) 
       lastCommonRoot = index; 
      else 
       break; 
     if (lastCommonRoot > -1){ 
      StringBuilder relativePath = new StringBuilder(); 
      for (index = lastCommonRoot + 1; index <absoluteDirectories.length; 
                     index++) 
       if (absoluteDirectories[index].length() > 0) 
        relativePath.append("..\\\\"); 
      for (index = lastCommonRoot + 1; index <relativeDirectories.length-1; 
                     index++) 
       relativePath.append(relativeDirectories[index] + "\\\\"); 
      relativePath.append(relativeDirectories[relativeDirectories.length - 1]); 
      return relativePath.toString();   
     } 
     else{ 
      throw new Exception("No common root found between working direcotry and filename"); 
     }    
    } 
14

En Java 7 también se puede utilizar la interfaz Path:

Path basePath = FileSystems.getDefault().getPath("C:\\projects\\project1\\module7\\submodule5\\fileA"); 
Path resolvedPath = basePath.getParent().resolve("..\\..\\module3\\submodule9\\subsubmodule32\\fileB"); // use getParent() if basePath is a file (not a directory) 
Path abolutePath = resolvedPath.normalize(); 
+0

Buena respuesta, pero necesitas reemplazar esos '\' con '\\' o no compilará –

1

Qué Es mejor que simplemente crear una utilidad que convierta rutas relativas a rutas absolutas es crear una utilidad que convierta cualquier ruta que se le pase en una ruta absoluta para que no tenga que verificar en el lado del cliente.

El siguiente código funciona para mí en ambos casos y he utilizado el tipo String en la firma del método (tanto en valor del parámetro y regreso):

public static String toAbsolutePath(String maybeRelative) { 
    Path path = Paths.get(maybeRelative); 
    Path effectivePath = path; 
    if (!path.isAbsolute()) { 
     Path base = Paths.get(""); 
     effectivePath = base.resolve(path).toAbsolutePath(); 
    } 
    return effectivePath.normalize().toString(); 
} 

Cambiar el código anterior para exponer Path tipos en la firma del método es trivial (y realmente más fácil) pero creo que el uso de String en la firma le da más flexibilidad.

-3

Ruta de Windows a la ruta completa de Java.

String winPath = downloadPath+"\\"+dir_contents[i].getName(); 
String absPath = winPath.replace("\\","\\\\"); 
5

cadena rutaAbsoluta = FileSystems.getDefault() getPath (mayBeRelativePath) .normalize() toAbsolutePath() toString()...;

+0

¿Puedes explicar un poco más de lo que eres ¿haciendo aquí? –

+1

'FileSystems.getDefault()' obtiene el sistema de archivos predeterminado. Para este sistema de archivos convierta una cadena 'mayBeRelativePath' en un objeto' Path'. 'normalize()' it, es decir, eliminar construcciones como '../ abc /../' de cualquier parte de la ruta. Transforme 'toAbsolutePath()' si aún no es un absoluto y obtenga la ruta como una cadena. – rssdev10

+0

@ rssdev10 Muchas gracias, esto funcionó muy bien en mis pruebas y es solo una línea en comparación con todas las demás respuestas que contienen 3-20 líneas para la misma cosa. – Leon

0

De su pregunta, si pudiera hacerlo bien, está buscando obtener una ruta absoluta desde la ruta relativa, entonces puede hacer lo siguiente.

File b = new File("../some/relative/path"); 
String absolute = b.getCanonicalPath(); // may throw IOException 

o notación abreviada puede ser,

String absolute = new File("../some/relative/path").getCanonicalPath(); 
Cuestiones relacionadas