Прочетете директория в JAR с InputStreamReader

И така, този въпрос е задаван милиони пъти, вярвах, и ги чета от няколко часа и опитвам няколко опции, дадени от някои хора, но нито една от тях не работи за мен.

Искам да изброя всички файлове в директория в JAR на приложението, така че в IDE това работи:

File f = new File(this.getClass().getResource("/resources/").getPath());

for(String s : f.list){
   System.out.println(s);
}

Това ми дава всички файлове в директорията.

Сега опитах и ​​това:

InputStream in = this.getClass().getClassLoader().getResourceAsStream("resources/");
    InputStreamReader inReader = new InputStreamReader(in);
    Scanner scan = new Scanner(inReader);

    while (scan.hasNext()) {
        String s = scan.next();
        System.out.println("read: " + s);
    }

    System.out.println("END OF LINE");

И от IDE принтира ВСИЧКИ файлове в директорията. Извън IDE отпечатва: "КРАЙ НА РЕД".

Сега мога да намеря запис в Jar и с това:

        String s = new File(this.getClass().getResource("").getPath()).getParent().replaceAll("(!|file:\\\\)", "");
        JarFile jar = new JarFile(s);

            JarEntry entry = jar.getJarEntry("resources");

        if (entry != null){
            System.out.println("EXISTS");
            System.out.println(entry.getSize());
        }

Това е ужасно кодиране, което трябваше да направя на този низ.

Както и да е... Не мога да получа списъка с ресурси в директорията "resources" в Jar... Как мога да направя това???


person Jh62    schedule 15.08.2013    source източник


Отговори (2)


Няма начин просто да получите филтриран списък с вътрешни ресурси, без първо да изброите съдържанието на Jar файла.

За щастие, това всъщност не е толкова трудно (и за мое щастие вие ​​сте свършили по-голямата част от тежката работа).

По принцип, след като имате препратка към JarFile, просто трябва да поискате неговия 'entries и да преминете през този списък.

Като проверите името JarEntry за необходимото съвпадение (т.е. resources), можете да филтрирате елементите, които искате...

Например...

import java.io.File;
import java.io.IOException;
import java.util.Enumeration;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;

public class ReadMyResources {

    public static void main(String[] args) {
        new ReadMyResources();
    }

    public ReadMyResources() {
        JarFile jf = null;
        try {            
            String s = new File(this.getClass().getResource("").getPath()).getParent().replaceAll("(!|file:\\\\)", "");
            jf = new JarFile(s);

            Enumeration<JarEntry> entries = jf.entries();
            while (entries.hasMoreElements()) {
                JarEntry je = entries.nextElement();
                if (je.getName().startsWith("resources")) {
                    System.out.println(je.getName());
                }
            }
        } catch (IOException ex) {
            ex.printStackTrace();
        } finally {
            try {
                jf.close();
            } catch (Exception e) {
            }
        }
    }

}

Внимание

Този тип въпроси всъщност се задават малко. Вместо да се опитвате да прочетете съдържанието на Jar по време на изпълнение, би било по-добре да създадете някакъв текстов файл, който съдържа списък на наличните ресурси.

Това може да бъде произведено от вашия процес на изграждане динамично, преди да бъде създаден Jar файлът. Би било много по-просто решение след това да прочетете този файл (чрез getClass().getResource(), например) и след това да потърсите всеки списък с ресурси в текстовия файл...IMHO

person MadProgrammer    schedule 15.08.2013
comment
Благодаря за отговора и последната забележка. По ирония на съдбата стигнах до същото решение, преди да се върна тук, за да прочета отговорите. Предполагам, че тогава е най-добрият начин. Също така друг начин би бил да създадете временна папка с всички ресурси, които трябва да четете по време на изпълнение във временна папка. - person Jh62; 15.08.2013
comment
Бих казал, че ресурсите като външни ресурси вероятно е по-лесното решение. Използването на решението за списък с файлове може да ви позволи действително да разположите множество списъци с ресурси (с едно и също) в множество Jars. Ще трябва да ги обедините, но това би означавало, че можете да получите достъп до ресурси в множество буркани, без да знаете къде всъщност се съхраняват - person MadProgrammer; 15.08.2013
comment
@MadProgrammer, бихте ли предоставили връзката, която демонстрира това, за да изброите всички файлове по време на процеса на изграждане? - person supertonsky; 09.06.2017
comment
@supertonsky Това ще зависи от това какъв процес на изграждане използвате. Ant може да го направи, Maven трябва да го може, в противен случай ще трябва да го направите на ръка - person MadProgrammer; 09.06.2017
comment
@MadProgrammer, maven трябва да е добре :) - person supertonsky; 09.06.2017
comment
@supertonsky Вероятно ще трябва да напишете нов плъгин ;) - По принцип между фазите на изграждане и пакетиране трябва да генерирате друг файл, който е списък с ресурсите, които искате - така че моите 10 секунди разследване включи това, което изброява няколко от начините, по които бихте могли да го направите - person MadProgrammer; 09.06.2017

За потребители на Spring Framework, погледнете PathMatchingResourcePatternResolver, за да направите нещо като следното:

PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
Resource[] resources = resolver.getResources("classpath:path/to/resource/*.*");

for (Resource resource : resources) {
    InputStream inStream = resource.getInputStream();
    // Do something with the input stream
}
person solimant    schedule 15.05.2018
comment
Толкова просто и работи като чар! Благодаря! Това трябва да е правилният отговор според мен. Не е нужно да сте потребител на Spring, за да използвате това, просто вземете буркана Spring... - person jhas; 17.09.2018