Flux.using读取UTF-8文件时FileInputStream未正常关闭问题咨询
问题原因
你当前实现出现FileInputStream未关闭的核心原因有两个:
- 你在
Flux.using的资源清理逻辑里只调用了Stream::close,仅关闭了BufferedReader.lines()返回的流对象,嵌套在内部的InputStreamReader、FileInputStream没有被纳入可靠的关闭链路 - 你贴的代码里存在多处拼写错误(
fileInptStream/StandarCharsets/BufferReader均为错误命名),会直接导致编译失败,也会干扰资源正常释放逻辑
最优解决方案
你完全不需要手动包装FileInputStream来指定编码,JDK自带的Files.lines已经提供了指定字符集的重载方法,从根源上避免多层流关闭的问题,也不会触发MalformedInput异常:
// 输入文件路径 Path ipPath = Paths.get("/some/path/large-input-file.txt"); Flux<String> stringFlux = Flux.using( () -> Files.lines(ipPath, StandardCharsets.UTF_8), Flux::fromStream, Stream::close );
这个实现是Project Reactor官方文档推荐的文件读取写法,所有IO资源的关闭逻辑由JDK和Flux托管,不会出现资源泄漏。
自定义包装流的正确写法
如果你后续有自定义流包装需求(比如加解密、解压处理),必须把所有创建的可关闭资源都纳入Flux的资源管理链路,按逆序逐层关闭,参考实现如下:
Path ipPath = Paths.get("/some/path/large-input-file.txt"); Flux<String> stringFlux = Flux.using( () -> { // 按从底层到上层的顺序创建IO流 FileInputStream fileInputStream = new FileInputStream(ipPath.toFile()); InputStreamReader isr = new InputStreamReader(fileInputStream, StandardCharsets.UTF_8); BufferedReader bufferedReader = new BufferedReader(isr); // 持有所有流的引用,不要只返回lineStream return new Object() { final Stream<String> lineStream = bufferedReader.lines(); final BufferedReader br = bufferedReader; final InputStreamReader isrWrapper = isr; final FileInputStream fis = fileInputStream; }; }, resource -> Flux.fromStream(resource.lineStream), resource -> { // try-with-resources会按声明逆序自动关闭所有资源 try (resource.fis; resource.isrWrapper; resource.br; resource.lineStream) { // 无需额外关闭逻辑 } catch (IOException e) { // 按需处理关闭时的异常,比如打印业务日志 } } );
内容的提问来源于stack exchange,提问作者Skazi
相关产品推荐
相关产品推荐

