Cómo obtener la ruta del directorio de recursos mediante programación

86

Tengo el siguiente diseño de directorio:

  • src
    • principal
      • Java
      • recursos
        • sql (scripts para base de datos)
        • primavera (configuración)
      • Aplicación Web

Dentro de una clase ServletContextListener, quiero acceder a los archivos del directorio SQL y enumerarlos. Básicamente, mi problema es con la ruta, porque sé que enumerar archivos en un directorio en pocas palabras es:

File folder = new File(path);
File[] listOfFiles = folder.listFiles();

Quizás podría usar el ServletContextEventObjeto para intentar construir una ruta haciaresources/sql

public void contextInitialized(ServletContextEvent event) {
    event.getServletContext(); //(getRealPath etc.)
}

¿Existe algo para establecer ese camino de una manera relativa, no codificada? Algo como new File("classpath:sql")(preferiblemente primavera si es posible) o ¿qué debo hacer con el servletContext al que apuntar resources/sql?

yamilmedina
fuente
Hay tres variantes de solución, según la situación: stackoverflow.com/a/56327069/715269
Gangnus

Respuestas:

69

Supongo que el contenido de src/main/resources/se copia WEB-INF/classes/dentro de su .war en el momento de la compilación. Si ese es el caso, puede hacerlo (sustituyendo los valores reales por el nombre de la clase y la ruta que se está cargando).

URL sqlScriptUrl = MyServletContextListener.class
                       .getClassLoader().getResource("sql/script.sql");
Dev
fuente
¡¡Gracias!! esto funcionó para mí, con esa URL, luego construyo la ruta para el nuevo archivo y finalmente obtengo los archivos en ese directorio.
yamilmedina
2
No necesita el archivo. Ya tienes una URL. Ni siquiera puede asumir que hay un archivo o un directorio en absoluto. Es posible que el WAR no se haya desempacado.
Marqués de Lorne
¿Qué significa MyServletContextListener aquí?
Tejesh Raut
@TejeshRaut Es un marcador de posición para una clase que implementa javax.servlet.ServletContextListener. Lo usé como ejemplo porque la pregunta tenía un fragmento del contextInitialized cual es un método definido por la ServletContextListenerinterfaz.
Dev
60

Finalmente, esto es lo que hice:

private File getFileFromURL() {
    URL url = this.getClass().getClassLoader().getResource("/sql");
    File file = null;
    try {
        file = new File(url.toURI());
    } catch (URISyntaxException e) {
        file = new File(url.getPath());
    } finally {
        return file;
    }
}

...

File folder = getFileFromURL();
File[] listOfFiles = folder.listFiles();
yamilmedina
fuente
11
¿Está seguro de utilizarlo "/sql"como parámetro? Tengo problemas con una barra inicial, pero "sql"funciona.
Abdull
2
Tenga en cuenta que puede obtener una URL diferente con this.getClass (). GetResource ("/ sql"));
ShadowGames
Esto no funcionará en todos los contenedores. Tomcat, por ejemplo.
Marqués de Lorne
16
import org.springframework.core.io.ClassPathResource;

...

File folder = new ClassPathResource("sql").getFile();
File[] listOfFiles = folder.listFiles();

Vale la pena señalar que esto limitará sus opciones de implementación, ClassPathResource.getFile()solo funciona si el contenedor ha explotado (descomprimido) su archivo war.

samlewis
fuente
6

Simplemente use la clase com.google.common.io.Resources . Ejemplo:

 URL url = Resources.getResource("file name")

Después de eso, tiene métodos como: .getContent (), .getFile (), .getPath (), etc.

grep
fuente
1
¿También admiten la obtención de recursos mientras se ejecuta el código desde un archivo jar?
Displee