Search code examples
javajarembedded-resource

getting all file names within a resource package and working for nonjar and jar running


I already apologize for the so unprecise titel but this problem has to be under special circumstances. I am currently writing a little Sokoban-game and I have some preset-games in various .txt files. Those files are located in /resources/presets/* .txt within the src-folder. So when I build a jar-file, they will be also located here: .../GameBox.jar!/resources/presets/*.txt

Reading already known textfiles from that package is no problem (I do it like that)

BufferedReader rd = new BufferedReader(new InputStreamReader(getClass().getResourceAsStream("/resources/presets/standard.txt")));

BUT I want to have a list of all textfiles within that package, so I can alternate between them and add new ones just by placing them in the folder.

This List of textfiles within the package should be created when the programm runs by a javac command or from within a jar-file.

I looked at some other stackoverflow codes here like this one:

List<String> getResourceFiles(String path) throws IOException{
    List<String> filenames = new ArrayList<>();
    try(InputStream in = getResourceAsStream(path);
        BufferedReader br = new BufferedReader(new InputStreamReader(in))) {
        String resource;
        while((resource=br.readLine())!=null){
            filenames.add(resource);
        }
    }
    return filenames;
}

private  InputStream getResourceAsStream(String resource){
    final InputStream in = getContextClassLoader().getResourceAsStream(resource);
    System.out.println(in);
    return in==null?getClass().getResourceAsStream(resource):in;
}

private  ClassLoader getContextClassLoader() {
    System.out.println(Thread.currentThread().getContextClassLoader());
    return Thread.currentThread().getContextClassLoader();
}

and this one:

public static List<String> getFiles(String paths) {
    List<String> filesList = new ArrayList<>();
    List<File> files = new ArrayList<>();
    for (final String path : paths.split(File.pathSeparator)) {
        final File file = new File(path);
        System.out.println(path);
        if( file.isDirectory()) {
            recurse(files, filesList, file);
        }
        else {
            filesList.add(file.getName());
        }
    }
    return filesList;
}
private static void recurse(List<File> filesList, List<String> files, File f) {
    File list[] = f.listFiles();
    for (File file : list) {
        if (file.isDirectory()) {
            recurse(filesList, files, file);
        }
        else {
            filesList.add(file);
            files.add(file.getName());

        }
    }
}

Those two different approaches both work for the programm runnning with the javac command but NONE of those work when I build a jar-file and try to run it.

I use Intellij to code and build the jar file if anyone is concerned about it

PS: I don't want to use new packages like spring (the PathMatchingResourcePatternResolver for example)


Solution

  • A Jar does not act like a file system (like as can be used as a File).

    The approach to pursue here, would be to include a text based file.list that is prepared (and included) when the Jar is built. The app. can fetch the list using something like:

    URL fileListURL = getClass().getResource("/resource/file.list");
    

    Then go on to read the list line by line before loading (or listing) each.