java - example - ¿Cómo puedo obtener un recurso "Carpeta" desde mi archivo jar?
get resources path java (9)
Tengo una carpeta / paquete de recursos en la raíz de mi proyecto, "no quiero" cargar un determinado archivo. Si quisiera cargar un determinado archivo, usaría class.getResourceAsStream y ¡estaría bien! Lo que realmente quiero hacer es cargar una "Carpeta" dentro de la carpeta de recursos, repetir los Archivos dentro de esa Carpeta y obtener un Stream para cada archivo y leer el contenido ... Suponer que los nombres de los Archivos no están determinados antes del tiempo de ejecución ... ¿Que debería hacer? ¿Hay alguna manera de obtener una lista de los archivos dentro de una Carpeta en su Archivo jar? Tenga en cuenta que el archivo Jar con los recursos es el mismo archivo jar desde el que se está ejecutando el código ...
Gracias por adelantado...
Dentro de mi archivo jar tenía una carpeta llamada Upload, esta carpeta tenía otros tres archivos de texto y necesitaba tener exactamente la misma carpeta y archivos fuera del archivo jar. Utilicé el siguiente código:
URL inputUrl = getClass().getResource("/upload/blabla1.txt");
File dest1 = new File("upload/blabla1.txt");
FileUtils.copyURLToFile(inputUrl, dest1);
URL inputUrl2 = getClass().getResource("/upload/blabla2.txt");
File dest2 = new File("upload/blabla2.txt");
FileUtils.copyURLToFile(inputUrl2, dest2);
URL inputUrl3 = getClass().getResource("/upload/blabla3.txt");
File dest3 = new File("upload/Bblabla3.txt");
FileUtils.copyURLToFile(inputUrl3, dest3);
El siguiente código devuelve la "carpeta" deseada como Ruta, independientemente de si está dentro de un contenedor o no.
private Path getFolderPath() throws URISyntaxException, IOException {
URI uri = getClass().getClassLoader().getResource("folder").toURI();
if ("jar".equals(uri.getScheme())) {
FileSystem fileSystem = FileSystems.newFileSystem(uri, Collections.emptyMap(), null);
return fileSystem.getPath("path/to/folder/inside/jar");
} else {
return Paths.get(uri);
}
}
Requiere java 7+.
Este link te dice cómo.
La magia es el método getResourceAsStream ():
InputStream is =
this.getClass().getClassLoader().getResourceAsStream("yourpackage/mypackage/myfile.xml")
Finalmente, encontré la solución:
final String path = "sample/folder";
final File jarFile = new File(getClass().getProtectionDomain().getCodeSource().getLocation().getPath());
if(jarFile.isFile()) { // Run with JAR file
final JarFile jar = new JarFile(jarFile);
final Enumeration<JarEntry> entries = jar.entries(); //gives ALL entries in jar
while(entries.hasMoreElements()) {
final String name = entries.nextElement().getName();
if (name.startsWith(path + "/")) { //filter according to the path
System.out.println(name);
}
}
jar.close();
} else { // Run with IDE
final URL url = Launcher.class.getResource("/" + path);
if (url != null) {
try {
final File apps = new File(url.toURI());
for (File app : apps.listFiles()) {
System.out.println(app);
}
} catch (URISyntaxException ex) {
// never happens
}
}
}
El segundo bloque simplemente funciona cuando ejecuta la aplicación en IDE (no con el archivo jar). Puede eliminarlo si no le gusta.
Otra solución, puede hacerlo usando ResourceLoader
esta manera:
import org.springframework.core.io.Resource;
import org.apache.commons.io.FileUtils;
@Autowire
private ResourceLoader resourceLoader;
...
Resource resource = resourceLoader.getResource("classpath:/path/to/you/dir");
File file = resource.getFile();
Iterator<File> fi = FileUtils.iterateFiles(file, null, true);
while(fi.hasNext()) {
load(fi.next())
}
Prueba lo siguiente.
Cree la ruta del recurso "<PathRelativeToThisClassFile>/<ResourceDirectory>"
Por ejemplo, si su ruta de clase es com.abc.package.MyClass y sus archivos resoure están dentro de src / com / abc / package / resources /:
URL url = MyClass.class.getResource("resources/");
if (url == null) {
// error - missing folder
} else {
File dir = new File(url.toURI());
for (File nextFile : dir.listFiles()) {
// Do something with nextFile
}
}
También puedes usar
URL url = MyClass.class.getResource("/com/abc/package/resources/");
Sé que esto fue hace muchos años. Pero solo para otras personas se encuentran con este tema. Lo que podría hacer es usar el método getResourceAsStream()
con la ruta del directorio, y la entrada Stream tendrá todos los nombres de los archivos de ese directorio. Después de eso, puede concat la ruta del directorio con cada nombre de archivo y llamar a getResourceAsStream para cada archivo en un bucle.
Simple ... usa OSGi. En OSGi puede iterar sobre las entradas de su paquete con findEntries y findPaths.
Tuve el mismo problema mientras intentaba cargar algunas configuraciones de hadoop de los recursos empaquetados en el contenedor ... tanto en el IDE como en el jar (versión de lanzamiento).
Encontré java.nio.file.DirectoryStream
para trabajar lo mejor posible para iterar sobre los contenidos del directorio tanto en el sistema de archivos local como en el jar.
String fooFolder = "/foo/folder";
....
ClassLoader classLoader = foofClass.class.getClassLoader();
try {
uri = classLoader.getResource(fooFolder).toURI();
} catch (URISyntaxException e) {
throw new FooException(e.getMessage());
} catch (NullPointerException e){
throw new FooException(e.getMessage());
}
if(uri == null){
throw new FooException("something is wrong directory or files missing");
}
/** i want to know if i am inside the jar or working on the IDE*/
if(uri.getScheme().contains("jar")){
/** jar case */
try{
URL jar = FooClass.class.getProtectionDomain().getCodeSource().getLocation();
//jar.toString() begins with file:
//i want to trim it out...
Path jarFile = Paths.get(jar.toString().substring("file:".length()));
FileSystem fs = FileSystems.newFileSystem(jarFile, null);
DirectoryStream<Path> directoryStream = Files.newDirectoryStream(fs.getPath(fooFolder));
for(Path p: directoryStream){
InputStream is = FooClass.class.getResourceAsStream(p.toString()) ;
performFooOverInputStream(is);
/** your logic here **/
}
}catch(IOException e) {
throw new FooException(e.getMessage());
}
}
else{
/** IDE case */
Path path = Paths.get(uri);
try {
DirectoryStream<Path> directoryStream = Files.newDirectoryStream(path);
for(Path p : directoryStream){
InputStream is = new FileInputStream(p.toFile());
performFooOverInputStream(is);
}
} catch (IOException _e) {
throw new FooException(_e.getMessage());
}
}