将资源数组转换为文件 ArrayList

Convert Resource array to File ArrayList

我正在尝试从 spring 应用程序的资源目录中读取文件。

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;
}

使用如下:

// Read all directories inside dbdata/mongo/ directory.
Resource[] resources = resourcePatternResolver.getResources("classpath:dbdata/mongo/*");
List<File> files = sortResources(Resource[] resources);

问题出在 sortResources 函数上。我想对 Resources 对象进行排序并将其转换为 Files 对象。

我无法让 .toArray() 工作,因为我收到以下错误:

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')

我也试过 .collect(Collectors.toList()) 但我得到了同样的错误。

有人可以帮我吗?

org.springframework.core.io.FileSystemResource 显然没有实现 Comparable<T> 接口,所以你对 sorted 的调用会抛出异常。

您可以将 Comparator 传递给 sorted,但将调用简单地移动到 sorted 之后 会更容易map 操作,因为 java.io.File 确实实现了 Comparable.

正如@f1sh 已经说过的 class FileSystemResource 不是 Comparable.

的子类型

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

要对文件进行排序,您需要为 sorted() 操作提供一个 Comparator 实例。另外,由于sorted()是一个stateful中间操作,所以最好放在filter()之后,这样可以减少需要排序的元素。事实上,像 sorted() 这样的有状态操作需要前一个操作的所有元素才能产生结果。它的缺点在并行计算下非常明显,因为包含有状态中间操作的管道可能需要多次传递数据或可能需要缓冲重要数据。

https://docs.oracle.com/javase/8/docs/api/java/util/stream/package-summary.html

这是您的代码的更新版本:

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