TheAlgorithms/Java · error · IOException

Empty or already closed stream provided

Error message

Empty or already closed stream provided

What it means

BufferedReader's constructor checks input.available() == -1 to detect a stream that is already exhausted or closed before any read begins. Note: this is an unusual use of available() (the InputStream contract says available() returns 0, not -1, when no bytes are available; -1 is non-standard), so this check primarily catches custom InputStream implementations that return -1 to signal closed/empty state. Thrown as IOException from the constructor.

Source

Thrown at src/main/java/com/thealgorithms/io/BufferedReader.java:48

    private int posRead = 0;
    private int bufferPos = 0;

    private boolean foundEof = false;

    private InputStream input;

    public BufferedReader(byte[] input) throws IOException {
        this(new ByteArrayInputStream(input));
    }

    public BufferedReader(InputStream input) throws IOException {
        this(input, DEFAULT_BUFFER_SIZE);
    }

    public BufferedReader(InputStream input, int bufferSize) throws IOException {
        this.input = input;
        if (input.available() == -1) {
            throw new IOException("Empty or already closed stream provided");
        }

        this.bufferSize = bufferSize;
        buffer = new byte[bufferSize];
    }

    /**
     * Reads a single byte from the stream
     */
    public int read() throws IOException {
        if (needsRefill()) {
            if (foundEof) {
                return -1;
            }
            // the buffer is empty, or the buffer has
            // been completely read and needs to be refilled
            refill();
        }

View on GitHub (pinned to fdfb9a395b)

Solutions

  1. Do not close the underlying stream before wrapping it; ensure single ownership.
  2. If using a custom InputStream, have available() return 0 (per java.io.InputStream contract) rather than -1 when no bytes are available.
  3. Check the stream is not already consumed before constructing the reader.

Example fix

// before
customStream.close();
new BufferedReader(customStream); // available() == -1

// after
// do not close beforehand; let BufferedReader own it
new BufferedReader(customStream);
Defensive patterns

Strategy: try-catch

Validate before calling

// Limited pre-check possible; available()==-1 is non-standard.
// Best: ensure the stream is open and not pre-closed before wrapping.
if (input == null) throw new IOException("stream is null");
new BufferedReader(input);

Try / catch

try {
    BufferedReader reader = new BufferedReader(input);
} catch (IOException e) {
    // stream was empty/closed; fall back to an empty source or rethrow with context
    throw new IOException("failed to open buffered reader: " + e.getMessage(), e);
}

Prevention

When it happens

Trigger: Constructing new BufferedReader(inputStream) where inputStream.available() returns -1 — typically a custom or already-closed stream. Passing a stream that was previously closed, or a custom InputStream whose available() is implemented to return -1.

Common situations: Wrapping a stream that was already closed elsewhere (double-close), using a custom InputStream subclass that returns -1 from available() when empty, or reusing a stream object after exhaustion.

Related errors


AI-assisted analysis of TheAlgorithms/Java@fdfb9a395b (2026-08-13). Data as JSON: /api/errors/9b80ee788578cd4b. Report an issue: GitHub.