调用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
相关产品推荐
相关产品推荐

