It's YourClass.class.getResourceAsStream
, not getClass()
, which has the potential to break if you subclass stuff.
the getResource mechanism fundamentally doesn't know what folders are and cannot give you a listing. Period. ClassLoaders are an abstraction, they can be implemented as reading jar files, directories on a disk, but also loading from a network, retrieving from a database, or generated on the fly, and crucially, there simply is no please list folder contents option, so whatever you find out there (and there's some libraries and such) are hacks that fail to work in such cases.
The common solution is to create a text file that lists the resources. Now you are no longer dependent on the unavailable 'list files' operation: Instead, you ask for all editions of that text file on any classpath entry, and then just read every file so listed. When applied to classes, this is called the SPI system (Service Provider Interface). Built into java.*
itself is the ability to read them, though they are designed for classes, not files, so I'm not sure the SPI system directly applies here. The principle works fine, though.
If you want this to be automated, as part of your build you'd have to generate that file automatically. Not sure how you'd do that with spring boot, you may have to maintain it by hand.
An example:
class CsvResource {
public CsvResource(String name) {
try (var in = CsvResource.class.getResourceAsStream("/csvfiles/" + name)) {
read(in); // you write this one.
}
}
public static List<String> getAvailableNames() {
try (var in = CsvResource.class.getResourceAsStream("/csvfiles/listing.txt")) {
Arrays.stream(
new String(in.readAllBytes, StandardCharsets.UTF_8).split("\s*\\n\s*"))
.filter(x -> !x.isEmpty())
.filter(x -> !x.startsWith("#"))
.collect(Collectors.toList());
}
}
}
It would be fair to catch IOException, especially for missing csvfiles, and rewrap into a runtime exception - that file not being there at runtime is a developer or devops error, and those should be Errors or at least RuntimeExceptions.