74 votos

abrir recurso con ruta relativa en java

En mi aplicación java necesito obtener algunos archivos y directorios.

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 carga la clase resourcesloader que cargará mis recursos (directorio y archivo).

Sobre el archivo, he intentado

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

para obtener la ruta real, pero esta forma no funciona...

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

¿Sugerencias? Gracias.

140voto

Johnny Puntos 705

Tuve problemas con el uso del getClass().getResource("filename.txt") método. Al leer las instrucciones de los documentos de Java, si su recurso no está en el mismo paquete que la clase desde la que está intentando acceder al recurso, entonces tiene que darle una ruta relativa que empiece por '/' . La estrategia recomendada es poner sus archivos de recursos bajo una carpeta "resources" en el directorio root. Así, por ejemplo, si usted tiene la estructura:

src/main/com/mycompany/myapp

entonces usted puede agregar una carpeta de recursos como se recomienda por maven en:

src/main/resources

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

src/main/resources/textfiles

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

src/main/resources/textfiles/myfile.txt

Aquí es donde entra el problema de la ruta estúpida. Digamos que tienes una clase en tu com.mycompany.myapp package y quiere acceder al myfile.txt de su carpeta de recursos. Algunos dicen que hay que dar el:

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

o

"/resources/textfiles/myfile.txt"

ambos están equivocados. Después de ejecutar mvn clean compile Los archivos y carpetas se copian en el:

myapp/target/classes 

carpeta. Pero la carpeta de recursos no está ahí, sólo las carpetas de la carpeta de recursos. Así que tienes:

myapp/target/classes/textfiles/myfile.txt

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

por lo que la ruta correcta a dar al getClass().getResource("") método es:

"/textfiles/myfile.txt"

aquí está:

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

Esto ya no devolverá null, sino que devolverá su clase. Espero que esto ayude a alguien. Me resulta extraño que el "resources" no se copia también, sino sólo las subcarpetas y los archivos que se encuentran directamente en la carpeta "resources" carpeta. Me parece lógico que la "resources" también se encontraría en la carpeta "myapp/target/classes"

43voto

jonathan.cone Puntos 3776

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

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

31voto

E-rich Puntos 1904

Con la esperanza de proporcionar información adicional para aquellos que no recogen esto tan rápidamente como otros, me gustaría proporcionar mi escenario, ya que tiene una configuración ligeramente diferente. Mi proyecto fue configurado 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

Tenía problemas para cargar mis recursos desde el res directorio. Quería que todos mis recursos estuvieran separados de mi código fuente (simplemente por motivos de gestión/organización). Por lo tanto, lo que tuve que hacer fue añadir el res al directorio ruta de construcción 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 al principio de la cadena de recursos porque estoy utilizando ClassLoader.getResource(String) en lugar de Class.getResource(String) .

10voto

Vikram Puntos 1363

@GianCarlo: Puedes probar a llamar a la propiedad System user.dir que te dará el Root de tu proyecto java y luego hacer el apéndice de esta ruta a tu 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);

2voto

resourcesloader.class.getClass()

Se puede desglosar en:

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

Lo que significa que estás tratando de cargar el recurso usando una clase bootstrap.

En su lugar, probablemente quieras algo como:

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

Si sólo javac advirtiera sobre la llamada a métodos estáticos en contextos no estáticos...

Iteramos.com

Iteramos es una comunidad de desarrolladores que busca expandir el conocimiento de la programación mas allá del inglés.
Tenemos una gran cantidad de contenido, y también puedes hacer tus propias preguntas o resolver las de los demás.

Powered by:

X