{"record":{"id":"e12924072b40d16a","repo":"TheAlgorithms/Java","slug":"input-stream-already-closed","errorCode":null,"errorMessage":"Input Stream already closed!","messagePattern":"Input Stream already closed!","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"src/main/java/com/thealgorithms/io/BufferedReader.java","lineNumber":184,"sourceCode":"        // try to fill in the maximum we can until\n        // we reach EOF\n        while (bufferPos < bufferSize) {\n            int read = input.read();\n            if (read == -1) {\n                // reached end-of-file, no more data left\n                // to be read\n                foundEof = true;\n                // rewrite the BUFFER_SIZE, to know that we've reached\n                // EOF when requested refill\n                bufferSize = bufferPos;\n            }\n            buffer[bufferPos++] = (byte) read;\n        }\n    }\n\n    private void assertStreamOpen() {\n        if (input == null) {\n            throw new IllegalStateException(\"Input Stream already closed!\");\n        }\n    }\n\n    public void close() throws IOException {\n        if (input != null) {\n            try {\n                input.close();\n            } finally {\n                input = null;\n            }\n        }\n    }\n}\n","sourceCodeStart":166,"sourceCodeEnd":198,"githubUrl":"https://github.com/TheAlgorithms/Java/blob/fdfb9a395b310167a66bd29e311e36e0e3e9b964/src/main/java/com/thealgorithms/io/BufferedReader.java#L166-L198","documentation":"BufferedReader.assertStreamOpen throws IllegalStateException (an unchecked exception) when input == null, which happens after close() sets the field to null. Any operation on a closed reader (read, peek, available, refill) triggers this via assertStreamOpen. This is the standard 'use after close' guard.","triggerScenarios":"Calling read(), peek(), readBlock(), or any read-driving method on a BufferedReader after close() was already called. close() nulls out the input field, and the next operation asserts it is non-null.","commonSituations":"Try-with-resources where the reader is used after the block, a manual close() followed by a read in an error path, or shared reader instances where one caller closes it and another continues.","solutions":["Do not use the reader after close(); structure code so close() is the last operation (try-with-resources is ideal).","If sharing a reader, coordinate ownership so only one caller closes it, after all readers finish.","Track closed state in your own flag and check before delegating if lifecycle is complex."],"exampleFix":"// before\nBufferedReader r = new BufferedReader(stream);\nString line = readAll(r);\nr.close();\nint b = r.read(); // IllegalStateException\n\n// after\ntry (BufferedReader r = new BufferedReader(stream)) {\n    String line = readAll(r);\n} // closed automatically; no use after","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"// IllegalStateException is unchecked; catch only if you must tolerate use-after-close.\ntry {\n    int b = reader.read();\n} catch (IllegalStateException e) {\n    // reader was closed; reopen or report\n    log.warn(\"reader already closed\", e);\n}","preventionTips":["Use try-with-resources to guarantee the reader is closed exactly once and never used after.","Do not share a single reader across components unless ownership/close is explicitly coordinated.","Treat use-after-close as a bug to fix at the call site, not an exception to swallow."],"tags":["io","stream","use-after-close","lifecycle","buffered-reader","illegal-state"],"backgroundTag":null,"analyzedSha":"fdfb9a395b310167a66bd29e311e36e0e3e9b964","analyzedAt":"2026-08-13T23:36:13.315Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}