una rutas ruta relativa obtener leer guardar especifica ejecuta donde crear archivos archivo aplicacion java file relative-path

rutas - ruta relativa java



¿Cómo resuelve Java una ruta relativa en el nuevo archivo()? (6)

Cuando su ruta comienza con un directorio raíz, es decir, C:/ en Windows o / en Unix o en la ruta de recursos de Java, se considera una ruta absoluta. Todo lo demás es relativo, entonces

new File("test.txt") is the same as new File("./test.txt") new File("test/../test.txt") is the same as new File("./test/../test.txt")

La principal diferencia entre getAbsolutePath y getCanonicalPath es que el primero concatena una ruta principal y secundaria, por lo que puede contener puntos: .. o . . getCanonicalPath siempre devolverá la misma ruta para un archivo en particular.

Nota: File.equals utiliza una forma abstracta de una ruta ( getAbsolutePath ) para comparar archivos, por lo que es posible que dos objetos File for the same no sean iguales y File s no sea seguro para usar en colecciones como Map o Set .

Estoy intentando comprender la forma en que Java resuelve la ruta relativa al crear un objeto File .

Sistema operativo utilizado: Windows

Para el siguiente fragmento, recibo una IOException porque no puede encontrar la ruta:

@Test public void testPathConversion() { File f = new File("test/test.txt"); try { f.createNewFile(); System.out.println(f.getPath()); System.out.println(f.getAbsolutePath()); System.out.println(f.getCanonicalPath()); } catch (Exception e) { e.printStackTrace(); } }

Mi comprensión aquí es que Java trata la ruta proporcionada como absoluta y devuelve un error cuando la ruta no existe. Entonces tiene sentido.

Cuando actualizo el código anterior para usar la ruta relativa:

@Test public void testPathConversion() { File f = new File("test/../test.txt"); try { f.createNewFile(); System.out.println(f.getPath()); System.out.println(f.getAbsolutePath()); System.out.println(f.getCanonicalPath()); } catch (Exception e) { e.printStackTrace(); } }

Crea un nuevo archivo y proporciona el siguiente resultado:

test/../test.txt C:/JavaForTesters/test/../test.txt C:/JavaForTesters/test.txt

En este caso, mi suposición es que, aunque la ruta proporcionada no existe, porque la ruta contiene "/../", java lo trata como una ruta relativa y crea el archivo en el user.dir . Entonces esto también tiene sentido.

Pero si actualizo la ruta relativa de la siguiente manera:

@Test public void testPathConversion() { File f = new File("test/../../test.txt"); try { f.createNewFile(); System.out.println(f.getPath()); System.out.println(f.getAbsolutePath()); System.out.println(f.getCanonicalPath()); } catch (Exception e) { e.printStackTrace(); } }

Luego recibo IOException: acceso denegado.

Mis preguntas son:

  1. ¿Por qué "test/../test.txt" se trata como una ruta relativa y crea el archivo en "user.dir" pero "test/../../test.txt" devuelve un error? ¿Dónde intenta crear el archivo para la ruta "test/../../test.txt" ?
  2. Cuando no se encuentra la ruta relativa especificada, el archivo parece estar creado en user.dir . Entonces, me parece que los dos escenarios siguientes hacen lo mismo:

    //scenario 1 File f = new File("test/../test.txt"); f.createNewFile(); //scenario 2 File f = new File("test.txt"); f.createNewFile();

Entonces, ¿hay un caso del mundo real donde uno usaría el escenario 1 en lugar del escenario 2?

Supongo que me estoy perdiendo algo obvio aquí o que he malentendido caminos relativos fundamentalmente. Revisé los documentos Java para File y no puedo encontrar una explicación para esto. Hay bastantes preguntas publicadas en Desbordamiento de pila sobre rutas relativas, pero las que busqué fueron para escenarios específicos y no exactamente sobre cómo se resuelven las rutas relativas.

Sería genial si alguien pudiera por favor explicarme cómo funciona esto o señalar algunos enlaces relacionados.


El directorio de trabajo es un concepto común en prácticamente todos los sistemas operativos y lenguajes de programas, etc. Es el directorio en el que se ejecuta su programa. Esto es usualmente (pero no siempre, hay formas de cambiarlo) el directorio en el que se encuentra la aplicación.

Las rutas relativas son aquellas que comienzan sin un especificador de unidad. Por lo tanto, en Linux no comienzan con un / , en Windows no comienzan con un C:/ , etc. Estos siempre comienzan desde su directorio de trabajo.

Los caminos absolutos son los que comienzan con un especificador de unidad (o máquina para rutas de red). Siempre van desde el inicio de ese disco.


En Windows y Netbeans puede establecer la ruta relativa como:

new FileReader("src//PACKAGE_NAME//FILENAME");

En Linux y Netbeans puede establecer la ruta relativa como:

new FileReader("src/PACKAGE_NAME/FILENAME");

Si tiene su código dentro de Source Packages , no sé si es el mismo para Eclipse u otro IDE


Hay un concepto de un working directory .
Este directorio está representado por a . (punto).
En caminos relativos, todo lo demás es relativo a él.

Simplemente pon el . (el directorio de trabajo) es donde ejecuta su programa.
En algunos casos, el directorio de trabajo puede cambiarse, pero en general esto es
qué representa el punto Creo que esto es C:/JavaForTesters/ en tu caso.

Entonces test/../test.txt significa: la test subdirectorio
en mi directorio de trabajo, luego un nivel arriba, luego el
archivo test.txt . Esto es básicamente lo mismo que test.txt .

Para más detalles, consulte aquí.

http://docs.oracle.com/javase/7/docs/api/java/io/File.html

http://docs.oracle.com/javase/tutorial/essential/io/pathOps.html


Las rutas relativas se pueden entender mejor si sabes cómo Java ejecuta el programa.

Existe un concepto de directorio de trabajo cuando se ejecutan programas en Java. Suponiendo que tiene una clase, por ejemplo, FileHelper que hace el IO en /User/home/Desktop/projectRoot/src/topLevelPackage/ .

Según el caso en el que invoque java para ejecutar el programa, tendrá un directorio de trabajo diferente. Si ejecuta su programa desde dentro e IDE, probablemente será projectRoot .

  • En este caso $ projectRoot/src : java topLevelPackage.FileHelper será src .

  • En este caso $ projectRoot : java -cp src topLevelPackage.FileHelper será projectRoot .

  • En este caso $ /User/home/Desktop : java -cp ./projectRoot/src topLevelPackage.FileHelper será Desktop .

(Assuming $ is your command prompt with standard Unix-like FileSystem. Similar correspondence/parallels with Windows system)

Por lo tanto, su raíz de ruta relativa (.) resuelve en su directorio de trabajo. Por lo tanto, para estar más seguro de dónde escribir archivos, se dice que considere el siguiente enfoque.

package topLevelPackage import java.io.File; import java.nio.file.Path; import java.nio.file.Paths; public class FileHelper { // Not full implementation, just barebone stub for path public void createLocalFile() { // Explicitly get hold of working directory String workingDir = System.getProperty("user.dir"); Path filePath = Paths.get(workingDir+File.separator+"sampleFile.txt"); // In case we need specific path, traverse that path, rather using . or .. Path pathToProjectRoot = Paths.get(System.getProperty("user.home"), "Desktop", "projectRoot"); System.out.println(filePath); System.out.println(pathToProjectRoot); } }

Espero que esto ayude.


Solo ligeramente relacionado con la pregunta, pero trata de entender esto. Muy poco intuitivo

import java.nio.file.*; class Main { public static void main(String[] args) { Path p1 = Paths.get("/personal/./photos/./readme.txt"); Path p2 = Paths.get("/personal/index.html"); Path p3 = p1.relativize(p2); System.out.println(p3); //prints ../../../../index.html !! } }