Как я могу получить ресурс "Папка" из моего файла jar?

У меня есть папка/пакет ресурсов в корне моего проекта, я "не хочу" загружать определенный файл. Если бы я захотел загрузить определенный файл, я бы использовал class.getResourceAsStream, и я был бы в порядке!! То, что я на самом деле хочу сделать, - загрузить "Папка" в папку ресурсов, зациклиться на файлах внутри этой Папки и получить поток для каждого файла и прочитать его содержимое... Предположим, что имена файлов не определены до времени выполнения... Что мне делать? Есть ли способ получить список файлов внутри папки в вашем файле jar? Обратите внимание, что Jar файл с ресурсами - это тот же самый файл jar, из которого выполняется код...

Спасибо заранее...

Ответ 1

Наконец, я нашел решение:

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

Второй блок работает только при запуске приложения в среде IDE (не с файлом jar), вы можете удалить его, если вам это не нравится.

Ответ 2

Попробуйте следующее.
Сделайте путь ресурса "<PathRelativeToThisClassFile>/<ResourceDirectory>" например. если ваш путь к классу - com.abc.package.MyClass и ваши файлы resoure находятся в файле 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
    }
}

Вы также можете использовать

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

Ответ 3

У меня была такая же проблема, когда я пытался загрузить некоторые конфигурации хаопов из ресурсов, упакованных в банку... как в среде IDE, так и на банке (версия выпуска).

Я обнаружил, что java.nio.file.DirectoryStream работает лучше, чтобы перебирать содержимое каталогов по локальной файловой системе и 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());
    }
}

Ответ 4

Простой... используйте OSGi. В OSGi вы можете перебирать записи Bundle с помощью findEntries и findPaths.

Ответ 5

Я знаю это много лет назад. Но только для других людей встречают эту тему. Вы можете использовать метод getResourceAsStream() с пути к каталогу, а входной поток будет иметь все имена файлов из этого каталога. После этого вы можете согласовать путь dir с каждым именем файла и вызвать getResourceAsStream для каждого файла в цикле.

Ответ 6

В моем файле jar у меня была папка с именем Upload, в этой папке было три других текстовых файла внутри, и мне нужно было иметь точно такую ​​же папку и файлы вне файла jar, я использовал следующий код:

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

Ответ 7

Другое решение, вы можете сделать это с помощью ResourceLoader следующим образом:

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

Ответ 8

Эта ссылка сообщает вам, как.

Магия - метод getResourceAsStream():

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