2009-02-21 19 views
66

En mi aplicación Java necesito obtener algunos archivos y directorios.recurso abierto con ruta relativa en Java

Esta es la estructura del programa:

./main.java 
./package1/guiclass.java 
./package1/resources/resourcesloader.java 
./package1/resources/repository/modules/ -> this is the dir I need to get 
./package1/resources/repository/SSL-Key/cert.jks -> this is the file I need to get 

guiclass cargas de la clase resourcesloader que cargará mis recursos (directorios y archivos).

Acerca del archivo, he intentado

resourcesloader.class.getClass().getResource("repository/SSL-Key/cert.jks").toString() 

con el fin de conseguir el camino real, pero de esta manera no funciona ...

Sobre el directorio no tengo ni idea de cómo hacerlo ..

Sugerencias? Gracias.

+1

class.getClass() no es lo mismo que class.getClassLoader(). También hay otra solución, getResourceAsStream() que usa una clase en el mismo paquete que su recurso. Para más detalles: http://tshikatshikaaa.blogspot.nl/2012/07/maven-how-to-access-filesdata-in.html. – JVerstry

+0

Véase también http://stackoverflow.com/questions/204784/how-to-construct-a-relative-path-in-java-from-two-absolute-paths-or-urls – Vadzim

Respuesta

37

Proporcione la ruta relativa al cargador de clases, no la clase de la que obtiene el cargador. Por ejemplo:

resourcesloader.class.getClassLoader().getResource("package1/resources/repository/SSL-Key/cert.jks").toString(); 
1

Haga el siguiente trabajo?

resourcesloader.class.getClass().getResource("/package1/resources/repository/SSL-Key/cert.jks") 

¿Hay algún motivo por el que no pueda especificar la ruta completa, incluido el paquete?

2
resourcesloader.class.getClass() 

se puede dividir a:

Class<resourcesloader> clazz = resourceloader.class; 
Class<Class> classClass = clazz.getClass(); 

Lo que significa que está tratando de cargar el recurso utilizando una clase de arranque.

En cambio es probable que quieren algo como:

resourcesloader.class.getResource("repository/SSL-Key/cert.jks").toString() 

Si solamente javac advirtió acerca de llamar a métodos estáticos en contextos no estáticos ...

7

Cuando se utiliza 'getResource' en una clase, un pariente la ruta se resuelve según el paquete en el que se encuentra la clase. Cuando utiliza 'getResource' en un ClassLoader, una ruta relativa se resuelve en función de la carpeta raíz.

Si utiliza una ruta absoluta, ambos métodos 'getResource' comenzarán en la carpeta raíz.

+0

No se olvide de los efectos de '' '/' '' – Gilberto

+0

@nbeyer ¿Por qué el uso de 'getResource' con ruta absoluta comienza en la carpeta raíz? ¿No es el propósito del camino absoluto ** absoluto **? –

126

Tuve problemas con el uso del método getClass().getResource("filename.txt"). Al leer las instrucciones de documentación de Java, si su recurso no está en el mismo paquete que la clase a la que intenta acceder, debe darle una ruta relativa que comienza con '/'. La estrategia recomendada es colocar los archivos de recursos en una carpeta de "recursos" en el directorio raíz.Así por ejemplo, si usted tiene la estructura:

src/main/com/mycompany/myapp 

continuación, puede agregar una carpeta de recursos según lo recomendado por el experto en:

src/main/resources 

, además, se puede añadir subcarpetas en la carpeta de recursos

src/main/resources/textfiles 

y diga que su archivo se llama myfile.txt por lo que tiene

src/main/resources/textfiles/myfile.txt 

Ahora aquí es donde entra el estúpido problema de ruta. Digamos que tiene una clase en su com.mycompany.myapp package, y desea acceder al archivo myfile.txt desde su carpeta de recursos. Algunos dicen que necesita para dar el:

"/main/resources/textfiles/myfile.txt" path 

o

"/resources/textfiles/myfile.txt" 

ambos están equivocados. Después me encontré mvn clean compile, los archivos y las carpetas se copian en el:

myapp/target/classes 

carpeta. Pero la carpeta de recursos no está allí, solo las carpetas en la carpeta de recursos. Por lo que tiene:

myapp/target/classes/textfiles/myfile.txt 

myapp/target/classes/com/mycompany/myapp/* 

por lo que el camino correcto para dar con el método getClass().getResource("") es:

"/textfiles/myfile.txt" 

aquí está:

getClass().getResource("/textfiles/myfile.txt") 

Esto ya no volverá nula, pero lo hará devuelve tu clase Espero que esto ayude a alguien. Es extraño para mí que la carpeta "resources" no se copie también, sino solo las subcarpetas y los archivos directamente en la carpeta "resources". Parecería lógico que la carpeta "resources" también se encuentra bajo "myapp/target/classes"

+1

En mi 'target/classes', solo puedo ver archivos en recursos principales y no en recursos de prueba. ¿Por qué? – Ava

+0

@Ava ¡Agregue la carpeta de prueba como su carpeta de origen y listo! –

8

@GianCarlo: Usted puede intentar llamar user.dir Propiedad del sistema que le dará raíz de su proyecto Java y luego hacer añada esta ruta a su ruta relativa, por ejemplo:

String root = System.getProperty("user.dir"); 
String filepath = "/path/to/yourfile.txt"; // in case of Windows: "\\path \\to\\yourfile.txt 
String abspath = root+filepath; 



// using above path read your file into byte [] 
File file = new File(abspath); 
FileInputStream fis = new FileInputStream(file); 
byte []filebytes = new byte[(int)file.length()]; 
fis.read(filebytes); 
+0

OP quería localizar un recurso en la ruta de clase (lo más probable en un jar generado durante la compilación th). Este método no proporciona una manera de lograr ese objetivo: no puede apuntar un 'Archivo' a un recurso dentro de un archivo jar, solo a una entrada adecuada en el sistema de archivos (por ejemplo, el propio jar). – Attila

29

En la esperanza de proporcionar información adicional para aquellos que no recoger esto tan rápido como otros, me gustaría ofrecer mi escenario ya que tiene una configuración ligeramente diferente. Mi proyecto fue instalado con la siguiente estructura de directorios (usando Eclipse):

 
Project/ 
    src/    // application source code 
    org/ 
     myproject/ 
     MyClass.java 
    test/    // unit tests 
    res/    // resources 
    images/   // PNG images for icons 
     my-image.png 
    xml/    // XSD files for validating XML files with JAXB 
     my-schema.xsd 
    conf/    // default .conf file for Log4j 
     log4j.conf 
    lib/    // libraries added to build-path via project settings 

que estaba teniendo problemas al cargar mis recursos de los res directorio. Quería que todos mis recursos se separaran de mi código fuente (simplemente para fines de gestión/organización).Por lo tanto, lo que tenía que hacer era poner los res directorio a la acumulación de ruta y luego acceder al recurso a través de:

static final ClassLoader loader = MyClass.class.getClassLoader(); 

// in some function 
loader.getResource("images/my-image.png"); 
loader.getResource("xml/my-schema.xsd"); 
loader.getResource("conf/log4j.conf"); 

NOTA: El / se omite desde el principio de la cadena de recursos porque estoy usando ClassLoader.getResource(String) en lugar de Class.getResource(String).

+1

. + 1 para sugerir ClassLoader – pyb

+0

¡La mejor respuesta al respecto! ¡La clave sobre no usar '/' al comienzo de una ruta de recursos fue la clave! – Kayhadrin

1

Continuando con las dos respuestas mencionadas anteriormente. El primero

resourcesloader.class.getClassLoader().getResource("package1/resources/repository/SSL-Key/cert.jks").toString(); 
resourcesloader.class.getResource("repository/SSL-Key/cert.jks").toString() 

¿Debería ser una misma cosa?

3

Para quienes usan eclipse + maven. Supongamos que intenta acceder al archivo images/pic.jpg en src/main/resources. Haciéndolo de esta manera:

ClassLoader loader = MyClass.class.getClassLoader(); 
File file = new File(loader.getResource("images/pic.jpg").getFile()); 

es perfectamente correcto, pero puede dar como resultado una excepción de puntero nulo. Parece que eclipse no reconoce las carpetas en la estructura de directorios maven como carpetas de origen de inmediato. Al eliminar y la carpeta src/main/resources de la lista de carpetas de origen del proyecto y ponerla de nuevo (proyecto> propiedades> ruta de compilación java> fuente> eliminar/agregar carpeta), pude resolver esto.

0

Hice una pequeña modificación en el liner de @ jonathan.cone (agregando .getFile()) para evitar la excepción del puntero nulo y establecer la ruta al directorio de datos. Esto es lo que funcionó para mí:

String realmID = new java.util.Scanner(new java.io.File(RandomDataGenerator.class.getClassLoader().getResource("data/aa-qa-id.csv").getFile().toString())).next(); 
0

Utilice esta:

resourcesloader.class.getClassLoader().getResource("/path/to/file").**getPath();**