I am trying to read files from resource directory on a spring application.
private File[] sortResources(Resource[] resources) {
assert resources != null;
File[] files = Arrays.stream(resources).sorted()
.filter(Resource::exists).filter(Resource::isFile).map(res -> {
try {
return res.getFile();
} catch (IOException e) {
throw new UncheckedIOException(e);
}
}
).toArray(File[]::new);
for (File f : files) {
System.out.println( f.getAbsolutePath() );
}
return files;
}
Using as follows:
// Read all directories inside dbdata/mongo/ directory.
Resource[] resources = resourcePatternResolver.getResources("classpath:dbdata/mongo/*");
List<File> files = sortResources(Resource[] resources);
The problem is on sortResources
function. I want to sort and convert the Resources objects to Files objects.
I can't get .toArray()
to work, since I get the following error:
Method threw 'java.lang.ClassCastException' exception.
class org.springframework.core.io.FileSystemResource cannot be cast to class java.lang.Comparable (org.springframework.core.io.FileSystemResource is in unnamed module of loader 'app'; java.lang.Comparable is in module java.base of loader 'bootstrap')
I also tried .collect(Collectors.toList())
but I get the same error.
Can someone help me on that?
CodePudding user response:
org.springframework.core.io.FileSystemResource
obviously does not implement the Comparable<T>
interface, so your call to sorted
throws an Exception.
You could either pass a Comparator
to sorted
, but it would be easier to simply move the call to sorted
after the map
operation, since java.io.File
does implement Comparable
.
CodePudding user response:
As @f1sh has already said the class FileSystemResource
is not a subtype of Comparable
.
To sort your files, you need to provide a Comparator
instance to the sorted()
operation. Besides, since sorted()
is a stateful intermediate operation, it would be better to place it after filter()
in order to reduce the elements to sort. In fact, a stateful operation like sorted()
needs all the elements of the previous operation to produce a result. Its drawback is quite visible under parallel computation as pipelines containing stateful intermediate operations may require multiple passes on the data or may need to buffer significant data.
https://docs.oracle.com/javase/8/docs/api/java/util/stream/package-summary.html
Here is the updated version of your code:
private File[] sortResources(Resource[] resources) {
assert resources != null;
File[] vetRes = new File[0];
return Arrays.stream(resources)
.filter(r -> r.exists() && r.isFile())
.map(r -> {
try {
return r.getFile();
} catch (IOException e) {
throw new UncheckedIOException(e);
}
})
.sorted(Comparator.comparing(File::getAbsolutePath))
.collect(Collectors.toList()).toArray(vetRes);
}