Spring中Resource数组转排序File数组抛出ClassCastException问题
报错原因
直接调用无参的Stream.sorted()会使用自然排序规则,要求流中元素必须实现Comparable接口。Spring提供的FileSystemResource没有实现这个接口,无法直接比较大小,所以触发类型转换异常。
这个错误和你后面用toArray()还是collect(Collectors.toList())没有关系,只要流执行到排序步骤就会抛错。
解决方法
给sorted()传入自定义比较器,明确Resource的排序规则即可,不需要修改Spring的Resource类。另外原代码有两个小问题需要修正:
- 排序逻辑放在过滤操作之前,会对不存在、非文件类型的无效资源也做排序,浪费性能,调整到filter之后更合理
- 调用
sortResources时传参写了Resource[] resources是语法错误,直接传变量名即可。
修正后的完整代码如下:
import org.springframework.core.io.Resource; import java.io.File; import java.io.IOException; import java.io.UncheckedIOException; import java.util.Arrays; import java.util.Comparator; import java.util.List; private File[] sortResources(Resource[] resources) { assert resources != null; File[] files = Arrays.stream(resources) .filter(Resource::exists) .filter(Resource::isFile) // 自定义排序规则,示例为按文件名升序排列,可按需调整 .sorted(Comparator.comparing(resource -> { try { return resource.getFile().getName(); } catch (IOException e) { throw new UncheckedIOException(e); } })) .map(resource -> { try { return resource.getFile(); } catch (IOException e) { throw new UncheckedIOException(e); } }) .toArray(File[]::new); for (File f : files) { System.out.println(f.getAbsolutePath()); } return files; }
调用方式修正为:
// 读取classpath下dbdata/mongo/目录内的所有资源 Resource[] resources = resourcePatternResolver.getResources("classpath:dbdata/mongo/*"); // 传参直接传入数组变量即可,不需要声明类型 File[] fileArray = sortResources(resources); // 如果需要List类型,自行转换即可 List<File> files = Arrays.asList(fileArray);
如果需要调整排序规则,只需要修改sorted()中比较器的逻辑即可:
- 按绝对路径排序:比较逻辑替换为
resource.getFile().getAbsolutePath() - 按文件最后修改时间排序:比较逻辑替换为
resource.getFile().lastModified() - 按文件大小排序:比较逻辑替换为
resource.getFile().length()
内容的提问来源于stack exchange,提问作者Vinicius Garcia
相关产品推荐
相关产品推荐

