You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

调用BufferedReader.readLine()抛出Stream closed异常求助

解决BufferedReader readLine()抛出Stream closed异常问题

问题描述

执行代码时,调用BufferedReader的readLine()方法抛出如下异常:

Exception in thread "main" java.io.IOException: Stream closed

异常发生在String word = reader.readLine();行,且multiReader.getReaders()返回100个文件对象。

完整代码

MergeShards.java

import java.io.BufferedReader;
import java.io.Writer;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.List;
import java.util.Objects;
import java.util.PriorityQueue;
import java.util.stream.Collectors;

public final class MergeShards {
    public static void main(String[] args) throws Exception {
        if (args.length != 2) {
            System.out.println("Usage: MergeShards [input folder] [output file]");
            return;
        }

        List<Path> inputs = Files.walk(Path.of(args[0]), 1).skip(1).collect(Collectors.toList());
        Path outputPath = Path.of(args[1]);

        try (MultiFileReader multiReader = new MultiFileReader(inputs)) {
            PriorityQueue<WordEntry> words = new PriorityQueue<>();
            for (BufferedReader reader : multiReader.getReaders()) {
                String word = reader.readLine();
                if (word != null) {
                    words.add(new WordEntry(word, reader));
                }
            }

            try (Writer writer = Files.newBufferedWriter(outputPath)) {
                while (!words.isEmpty()) {
                    WordEntry entry = words.poll();
                    writer.write(entry.word);
                    writer.write(System.lineSeparator());
                    String word = entry.reader.readLine();
                    if (word != null) {
                        words.add(new WordEntry(word, entry.reader));
                    }
                }
            }
        }
    }

    private static final class WordEntry implements Comparable<WordEntry> {
        private final String word;
        private final BufferedReader reader;

        private WordEntry(String word, BufferedReader reader) {
            this.word = Objects.requireNonNull(word);
            this.reader = Objects.requireNonNull(reader);
        }

        @Override
        public int compareTo(WordEntry other) {
            return word.compareTo(other.word);
        }
    }
}

MultiFileReader.java

import java.io.BufferedReader;
import java.io.Closeable;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public final class MultiFileReader implements Closeable {

    private final List<BufferedReader> readers;

    public MultiFileReader(List<Path> paths) {
        readers = new ArrayList<>(paths.size());
        try {
            for (Path path : paths) {
                readers.add(Files.newBufferedReader(path));
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            close();
        }
    }

    public List<BufferedReader> getReaders() {
        return Collections.unmodifiableList(readers);
    }

    @Override
    public void close() {
        for (BufferedReader reader : readers) {
            try {
                reader.close();
            } catch (Exception ignored) {
            }
        }
    }
}

问题原因

核心问题出在MultiFileReader的构造函数中:

  • 构造函数的finally块直接调用了close()方法,导致构造函数执行完成前就关闭了所有创建的BufferedReader实例。
  • 后续在try-with-resources块中尝试使用这些reader时,它们已经处于关闭状态,调用readLine()自然抛出Stream closed异常。
  • 另外,try-with-resources会自动调用MultiFileReader的close()方法,不需要在构造函数中提前关闭。

解决方案

修改MultiFileReader的构造函数,移除finally块中的close()调用,让try-with-resources机制在合适时机自动关闭资源;同时优化异常处理,避免资源泄漏。

修改后的MultiFileReader.java代码:

import java.io.BufferedReader;
import java.io.Closeable;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public final class MultiFileReader implements Closeable {

    private final List<BufferedReader> readers;

    public MultiFileReader(List<Path> paths) throws IOException {
        readers = new ArrayList<>(paths.size());
        try {
            for (Path path : paths) {
                readers.add(Files.newBufferedReader(path));
            }
        } catch (IOException e) {
            // 发生异常时先关闭已创建的reader,避免资源泄漏
            close();
            throw e; // 重新抛出异常,让调用方处理初始化失败情况
        }
    }

    public List<BufferedReader> getReaders() {
        return Collections.unmodifiableList(readers);
    }

    @Override
    public void close() {
        for (BufferedReader reader : readers) {
            try {
                reader.close();
            } catch (Exception ignored) {
            }
        }
    }
}

内容的提问来源于stack exchange,提问作者Ebillson GRAND JEAN

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 07:16:28