Ich habe einen Ressourcenordner/-paket im Stammverzeichnis meines Projekts. Ich möchte eine bestimmte Datei "nicht" laden. Wenn ich eine bestimmte Datei laden wollte, würde ich class.getResourceAsStream verwenden und es würde mir gut gehen !! Was ich eigentlich tun möchte, ist, einen "Ordner" im Ressourcenordner zu laden, die Dateien in diesem Ordner in einer Schleife zu durchlaufen und einen Stream zu jeder Datei zu erhalten und den Inhalt zu lesen ... Was soll ich machen? Gibt es eine Möglichkeit, eine Liste der Dateien in einem Ordner in Ihrer JAR-Datei abzurufen? Beachten Sie, dass die JAR-Datei mit den Ressourcen dieselbe JAR-Datei ist, von der der Code ausgeführt wird ...
Danke im Voraus...
Zum Schluss habe ich die Lösung gefunden:
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
}
}
}
Der zweite Block funktioniert nur, wenn Sie die Anwendung unter IDE ausführen (nicht mit der JAR-Datei). Sie können sie entfernen, wenn Sie das nicht mögen.
Versuche Folgendes.
Machen Sie den Ressourcenpfad "<PathRelativeToThisClassFile>/<ResourceDirectory>"
E.g. Wenn Ihr Klassenpfad com.abc.package.MyClass lautet und sich Ihre Ressourcendateien innerhalb von src/com/abc/package/resources/befinden:
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
}
}
Sie können auch verwenden
URL url = MyClass.class.getResource("/com/abc/package/resources/");
Ich weiß, das ist vor vielen Jahren. Aber nur, wenn andere Leute auf dieses Thema stoßen. Was Sie tun könnten, ist, die getResourceAsStream()
-Methode mit dem Verzeichnispfad zu verwenden, und der Eingabestrom enthält alle Dateinamen aus diesem Verzeichnis. Danach können Sie den Verzeichnispfad mit jedem Dateinamen zusammenführen und für jede Datei in einer Schleife getResourceAsStream aufrufen.
Ich hatte das gleiche Problem in den Händen, als ich versuchte, einige Hadoop-Konfigurationen von Ressourcen zu laden, die in das Gefäß gepackt waren ... sowohl auf der IDE als auch auf dem Gefäß (Release-Version).
Ich fand Java.nio.file.DirectoryStream
am besten, um Verzeichnisinhalte sowohl über das lokale Dateisystem als auch über jar zu durchlaufen.
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());
}
}
Der folgende Code gibt den gewünschten "Ordner" als Pfad zurück, unabhängig davon, ob er sich in einem Glas befindet oder nicht.
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);
}
}
Benötigt Java 7+.
Eine andere Lösung können Sie mit ResourceLoader
wie folgt ausführen:
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())
}
Einfach ... benutze OSGi. In OSGi können Sie die Einträge Ihres Bundles mit findEntries und findPaths durchlaufen.