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 tout irait bien !! Ce que je veux réellement faire est de charger un "dossier" dans le dossier de ressources, de boucler sur les fichiers de ce dossier et d'obtenir un flux pour chaque fichier et de lire le contenu ... Supposons que les noms de fichiers ne sont pas déterminés avant l'exécution ... Que devrais-je faire? Existe-t-il un moyen d’obtenir une liste des fichiers d’un dossier dans votre fichier jar? Notez que le fichier JAR avec les ressources est le même fichier JAR à partir duquel le code est exécuté ...
Merci d'avance...
Finalement, j'ai trouvé la solution:
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
}
}
}
Le second bloc ne fonctionne que lorsque vous exécutez l'application sur IDE (pas avec le fichier jar). Vous pouvez le supprimer si vous n'aimez pas cela.
Essayez ce qui suit.
Définir le chemin de la ressource "<PathRelativeToThisClassFile>/<ResourceDirectory>"
E.g. 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 cela fait plusieurs années. Mais juste pour les autres personnes rencontrées dans ce sujet… .. Ce que vous pourriez faire est d'utiliser la méthode getResourceAsStream()
avec le chemin du répertoire et le flux d'entrée aura tous les noms de fichiers de ce répertoire. Après cela, vous pouvez concatter le chemin du répertoire avec chaque nom de fichier et appeler getResourceAsStream pour chaque fichier d'une boucle.
J'avais le même problème lorsque j'essayais de charger des configurations hadoop à partir de ressources contenues dans le fichier jar ... à la fois sur le IDE et sur le fichier jar (version publiée).
J'ai trouvé que Java.nio.file.DirectoryStream
fonctionnait de manière optimale pour parcourir le contenu du répertoire sur le système de fichiers local et le fichier 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());
}
}
Le code suivant renvoie le "dossier" souhaité en tant que chemin, qu'il soit ou non à l'intérieur d'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<File> 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 lot avec findEntries et findPaths.