Close a Scanner by calling the close() method on your Scanner object
When you create a Scanner object in Java to read input from a file, keyboard, or network stream, you need to close it when you're done. Calling close() on the Scanner tells Java to release the underlying resource — whether that's a file handle, network connection, or input stream — so other parts of your program or other programs can use it.
The simplest way is a single line: scanner.close(); placed after your last Scanner operation. If you forget to close a Scanner, the resource stays open in memory until your program ends, which wastes system resources and can cause problems if your program runs for a long time or opens many Scanners.
Key Takeaways
- Call scanner.close() after you finish reading to release the underlying file or stream resource.
- Use try-with-resources (try with parentheses) to close the Scanner automatically, even if an error occurs.
- Closing a Scanner also closes the underlying stream, so don't close the Scanner if you need to keep reading from that stream elsewhere.
- Forgetting to close Scanners can cause resource leaks, especially in programs that create many Scanner objects.
The basic close() method
The most direct approach is to call close() when you're finished reading:
Scanner scanner = new Scanner(new File("data.txt")); while (scanner.hasNextLine()) { String line = scanner.nextLine(); System.out.println(line); } scanner.close();
This works, but it has a weakness: if an exception occurs inside the while loop, the close() statement never runs. The Scanner stays open, and the file handle remains locked. For small programs this might not matter, but in production code or long-running applications, unclosed resources pile up.
Use try-with-resources to close automatically
Java 7 introduced try-with-resources, a cleaner way to handle closing. You declare the Scanner inside parentheses after the try keyword, and Java closes it automatically when the try block exits — whether the code succeeds or throws an exception:
try (Scanner scanner = new Scanner(new File("data.txt"))) { while (scanner.hasNextLine()) { String line = scanner.nextLine(); System.out.println(line); } } catch (FileNotFoundException e) { System.out.println("File not found"); }
This is the recommended pattern in modern Java. The Scanner closes automatically after the try block, even if an exception occurs. You still catch exceptions separately if you need to handle them, but the closing happens no matter what.
What happens when you close a Scanner
Calling close() on a Scanner closes the underlying stream or file. If you created the Scanner from a File, the file handle is released. If you created it from System.in (keyboard input), that stream closes too. If you created it from a network socket or any other InputStream, that resource is released.
This is important: if you pass an existing InputStream to the Scanner constructor, closing the Scanner also closes that stream. So if you have code like this, closing the Scanner will close System.in, which usually isn't what you want:
Scanner scanner = new Scanner(System.in); // ... read input ... scanner.close(); // This closes System.in too
In this case, you might skip the close() call, or wrap System.in in a stream that you don't mind closing. For file-based Scanners, closing is always safe and recommended.
Handling multiple Scanners
If your program opens several Scanners — reading from different files or streams — close each one when you're done with it. Try-with-resources handles this naturally:
try (Scanner file1 = new Scanner(new File("input1.txt")); Scanner file2 = new Scanner(new File("input2.txt"))) { // read from both } catch (FileNotFoundException e) { System.out.println("File not found"); }
You can declare multiple resources separated by semicolons, and Java closes them all in reverse order when the try block exits. This prevents resource leaks even if you're juggling several open files.
Checking if a Scanner is closed
After calling close(), you can check whether a Scanner is still open by calling isClosed():
scanner.close(); if (scanner.isClosed()) { System.out.println("Scanner is closed"); }
If you try to read from a closed Scanner, it throws a NoSuchElementException. In practice, you rarely need to check isClosed() — just make sure your code doesn't try to read after closing.
Common mistakes when closing Scanners
One mistake is closing the Scanner too early. If you close it inside a loop and then try to read again in the next iteration, you'll get an error. Close only after all reading is complete.
Another mistake is closing System.in when you don't mean to. If you create a Scanner from System.in and close it, the keyboard input stream closes for the entire program. Use try-with-resources with a file-based Scanner instead, or skip closing if the Scanner wraps System.in.
A third mistake is ignoring exceptions. If opening a file throws FileNotFoundException before the Scanner is created, there's nothing to close. But if the Scanner is created and then an exception occurs during reading, try-with-resources ensures the close() still runs.
Frequently Asked Questions
What happens if I don't close a Scanner?
The underlying file or stream stays open in memory until your program ends or garbage collection runs. In short programs this usually doesn't matter, but in long-running applications or programs that open many Scanners, unclosed resources accumulate and can cause the program to run out of file handles or memory.
Can I close a Scanner more than once?
Yes. Calling close() on an already-closed Scanner does nothing — it doesn't throw an error. This is why try-with-resources is safe even if you manually close the Scanner before the try block exits.
Should I close a Scanner created from System.in?
No. Closing a Scanner created from System.in closes the keyboard input stream for your entire program. If you need to read from the keyboard multiple times, create one Scanner at the start and don't close it, or create a new Scanner each time and skip the close() call.
Does close() throw an exception?
close() can throw an IOException if closing the underlying stream fails, though this is rare. When using try-with-resources, any exception from close() is suppressed if an exception already occurred in the try block, but it's still thrown if the try block succeeds. In practice, you rarely need to catch exceptions from close().
What's the difference between close() and reset()?
close() releases the underlying resource and closes the Scanner permanently. reset() clears the Scanner's internal state (like the delimiter pattern) but doesn't close the underlying stream. Use reset() if you want to keep reading but change how the Scanner parses input; use close() when you're done reading entirely.