Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

reader.readLine() of BufferedReader causes this: Exception in thread "main" java.io.IOException: Stream closed

Here is a code snippet from my main Java function:

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

Here is how I get my BufferedReader readers from another Java file:

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

But for some reason, when I compile my code here is what I get:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

This is the error generated when I compile my code

The error happens exactly at the line where I wrote String word = reader.readLine(); and what’s weird is that reader.readLine() is not null, in fact multiReader.getReaders() returns a list of 100 objects (they are files read from a directory). I would like some help solving that issue.

I posted where the issue is, now let me provide a broader view of my code. To run it, it suffices to compile it under the src/ directory doing javac *.java and java MergeShards shards/ sorted.txt provided that shards/ is present under src/ and contains .txt files in my scenario.

  • This is MergeShards.java where I have my main function:
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);
        }
    }
}
  • This is my MultiFileReader.java file:
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) {
            }
        }
    }
}

>Solution :

The finally block in your constructor closes all of your readers. Remove that.

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();
    } /* Not this. finally {
        close();
    } */
}
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading