Comment puis-je obtenir une ressource «Dossier» depuis mon fichier jar?

J’ai un dossier / package de ressources à la racine de mon projet, je “ne veux” pas charger un certain fichier. Si je voulais charger un certain fichier, j’utiliserais class.getResourceAsStream et ça irait bien !! Ce que je veux réellement faire, c’est charger un “dossier” dans le dossier des ressources, faire une boucle sur les fichiers dans ce dossier et obtenir un stream sur chaque fichier et lire le contenu … Supposons que les noms de fichiers ne sont pas déterminés avant l’exécution … Que devrais-je faire? Y a-t-il un moyen d’obtenir une liste des fichiers dans un dossier dans votre fichier jar? Notez que le fichier Jar contenant les ressources est le même fichier JAR à partir duquel le code est exécuté …

Merci d’avance…

Enfin, j’ai trouvé la solution:

final Ssortingng 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 ensortinges = jar.ensortinges(); //gives ALL ensortinges in jar while(ensortinges.hasMoreElements()) { final Ssortingng name = ensortinges.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 } } } 

Le deuxième bloc ne fonctionne que lorsque vous exécutez l’application sur l’IDE (pas avec le fichier jar), vous pouvez le supprimer si vous n’aimez pas cela.

Essayez ce qui suit
Définissez le chemin d’access à la ressource "/" Par exemple, si votre chemin de classe est com.abc.package.MyClass et que vos fichiers de ressources se trouvent dans 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 } } 

Vous pouvez aussi utiliser

 URL url = MyClass.class.getResource("/com/abc/package/resources/"); 

Je sais que c’est il y a de nombreuses années. Mais juste pour d’autres personnes rencontrent ce sujet. Ce que vous pouvez faire est d’utiliser la méthode getResourceAsStream() avec le chemin du répertoire, et le stream d’entrée aura tous les noms de fichiers de ce répertoire. Après cela, vous pouvez concaténer le chemin d’access avec chaque nom de fichier et appeler getResourceAsStream pour chaque fichier d’une boucle.

J’ai eu le même problème aux mains pendant que j’essayais de charger des configurations de hadoop à partir de ressources contenues dans le fichier jar … à la fois sur l’IDE et sur le fichier jar (version finale).

J’ai trouvé java.nio.file.DirectoryStream fonctionnant le mieux possible pour parcourir le contenu des répertoires sur le système de fichiers local et sur jar.

 Ssortingng 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.toSsortingng() begins with file: //i want to sortingm it out... Path jarFile = Paths.get(jar.toSsortingng().subssortingng("file:".length())); FileSystem fs = FileSystems.newFileSystem(jarFile, null); DirectoryStream directoryStream = Files.newDirectoryStream(fs.getPath(fooFolder)); for(Path p: directoryStream){ InputStream is = FooClass.class.getResourceAsStream(p.toSsortingng()) ; performFooOverInputStream(is); /** your logic here **/ } }catch(IOException e) { throw new FooException(e.getMessage()); } } else{ /** IDE case */ Path path = Paths.get(uri); try { DirectoryStream directoryStream = Files.newDirectoryStream(path); for(Path p : directoryStream){ InputStream is = new FileInputStream(p.toFile()); performFooOverInputStream(is); } } catch (IOException _e) { throw new FooException(_e.getMessage()); } } 

Le code suivant renvoie le “dossier” souhaité en tant que chemin, qu’il soit ou non dans un fichier jar.

  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); } } 

Nécessite java 7+.

Une autre solution, vous pouvez le faire en utilisant ResourceLoader comme ceci:

 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 fi = FileUtils.iterateFiles(file, null, true); while(fi.hasNext()) { load(fi.next()) } 

Simple … utilisez OSGi. Dans OSGi, vous pouvez parcourir les entrées de votre ensemble avec findEnsortinges et findPaths.

Dans mon fichier jar, j’avais un dossier appelé Upload, ce dossier contenait trois autres fichiers texte et je devais avoir exactement le même dossier et les mêmes fichiers en dehors du fichier jar, j’ai utilisé le code ci-dessous:

 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); 

Comme le soulignent les autres réponses, une fois que les ressources sont dans un fichier jar, les choses deviennent vraiment laides. Dans notre cas, cette solution:

https://stackoverflow.com/a/13227570/516188

fonctionne très bien dans les tests (puisque lorsque les tests sont exécutés, le code n’est pas compressé dans un fichier jar), mais ne fonctionne pas lorsque l’application fonctionne normalement. Donc ce que j’ai fait c’est … Je code le nom de la liste des fichiers dans l’application, mais j’ai un test qui lit la liste réelle du disque (peut le faire depuis que ça fonctionne dans les tests) et échoue si la liste ne correspond pas à la liste renvoyée par l’application.

De cette façon, j’ai un code simple dans mon application (sans astuces), et je suis sûr que je n’ai pas oublié d’append une nouvelle entrée à la liste grâce au test.

Ce lien vous indique comment.

La magie est la méthode getResourceAsStream ():

 InputStream is = this.getClass().getClassLoader().getResourceAsStream("yourpackage/mypackage/myfile.xml")