Home > database >  Convert Resource array to File ArrayList
Convert Resource array to File ArrayList

Time:06-03

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.

https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/core/io/FileSystemResource.html

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);
}
  • Related