3

I asked this question yesterday. I think I got the right answer, but one of the other answers left me with a question. If I have code like this:

File file = new File("somefile.txt");
try (Scanner in = new Scanner(file)) {
    //do something but don't explicitly call file.close()
}

Is this wrong? From what I understand the try-with-resources statement will close a resource if that resource implements Closeable or AutoCloseable. In my mind I equate this to using the with statement to open file resources in Python. But the answer from @David Newcomb says that Scanner is not Closeable.

I looked at the Java source and I found the line:

public final class Scanner implements Iterator<String>, Closeable {

That means to me that I am safe using try-with-resources and that the file resource will be closed at the end of the try block without explicitly calling file.close(). Am I right or should I be doing something differently?

Community
  • 1
  • 1
noel
  • 2,257
  • 3
  • 24
  • 39
  • 2
    Java has this great thing calld the javadoc, which tells you which interfaces every class implements: http://docs.oracle.com/javase/6/docs/api/ – JB Nizet May 07 '13 at 11:50
  • That is not a "great thing" or an answer to my question. Also interesting to note though because you pointed it out is that, according to the javadoc, java6 Scanner does not implement Closeable but Java7 does. – noel May 07 '13 at 11:54
  • 2
    You're asking if you shoul call file.close(). Look at the javadoc of File, and you'll see that it doesn't have any clsoe() method and doesn't implement Closeable. Look at the javadoc of Scanner, and you'll see that it implements Closeable. – JB Nizet May 07 '13 at 11:56
  • 1
    @shakabra You'll find that some people on SO don't really like to have trivial logical reasoning outsourced to them. Ask questions where you need a problem resolved, not where you need a security blanket when it comes to drawing the obvious conclusion from data already available to you. You could've easily verified this with a few clicks through the JDK source to look at the implementation of `Scanner.close()`: http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/7-b147/java/util/Scanner.java#Scanner.close%28%29, or by stepping through it in a debugger. – millimoose May 07 '13 at 12:00
  • @millimoose I don't think leaving resources open is trivial logic. And nothing is obvious about Java. Thanks for the constructive input though. – noel May 07 '13 at 12:06
  • @shakabra By trivial logic, I meant the inference process: "*try-with-resources* will call `close()` on a `Closeable`" (which is the whole point of the construct) AND "`Scanner` is AutoCloseable" (which the Javadoc tells you) AND "`Scanner.close()` will `close()` the underlying resource if it's `Closeable`" (also in the Javadocs) IMPLIES "*try-with-resources* will ultimately close the underlying resource if it's `Closeable`". – millimoose May 07 '13 at 12:15
  • @shakabra The only not entirely obvious piece of that puzzle is "is the underlying resource `Closeable`", since `File` is not and the person who answered your linked question mislead you a little there. That said, the constructor `Scanner(File)` is trivial, opens a `FileInputStream` and uses its `FileChannel`, all of which are indeed `Closeable`. – millimoose May 07 '13 at 12:17
  • Last, but not least, it seems ridiculous that `Scanner` would simply leak resources anytime you use that constructor and thus can't manage the underlying resource at all. – millimoose May 07 '13 at 12:18
  • @millimoose I understand you and you're correct. I just wasn't sure if I was correct. – noel May 07 '13 at 12:18

1 Answers1

5

So now we have no doubts that try-with-resources will call Scanner.close(). Now lets see Scanner.close API:

If this scanner has not yet been closed then if its underlying readable also implements the Closeable interface then the readable's close method will be invoked.

Since Scanner was created with File argument, it will create FileInputStream internally and will close it automatically. File object does not need closing since its not a Closeable resource.

Community
  • 1
  • 1
Evgeniy Dorofeev
  • 133,369
  • 30
  • 199
  • 275
  • This is what I was thinking too. I just wanted to run it by some more experienced Java guys. – noel May 07 '13 at 11:52