Reading from a file
We have seen that a Scanner
can be constructed to read from
System.in
, and in previous labs we have seen
examples in which a Scanner reads its input from a String. We can also
construct a Scanner
to read from other kinds of input streams, and in
particular we can use a Scanner
to read from a text file.
With very few changes, we can rewrite the line numberer to read from a file.
package lab6; import java.io.File; import java.io.FileNotFoundException; import java.util.Scanner; public class LineNumberer2 { public static void main(String[] args) throws FileNotFoundException { File file = new File("story.txt"); Scanner scanner = new Scanner(file); int lineCount = 1; while (scanner.hasNextLine()) { String line = scanner.nextLine(); System.out.print(lineCount + " "); System.out.println(line); lineCount += 1; } scanner.close(); } }
Try this code out! To run in Eclipse, the file story.txt must be present in the project directory.
Try changing the filename to something invalid and
see what happens.
When the file you've named in the Scanner
constructor isn't there, the program fails prematurely and something called an exception is generated, in this case a
FileNotFoundException
. You have seen some kinds of exceptions in previous labs. The FileNotFoundException
is a bit different than the exceptions we've seen before, because the compiler requires us to declare in the method heading
that this exception might occur:
public static void main(String[] args) throws FileNotFoundException
The main change is the way that we construct the Scanner
. First, we
create a File
object by giving the constructor the name of the file we
want to read. Then we use the File
object to construct our Scanner
:
File file = new File("story.txt"); Scanner scanner = new Scanner(file);When we construct the
Scanner
from the given file, the file
is opened. This means that the operating system gets involved with finding the
actual file on the hard drive and preparing to read its contents. When you're
finished reading a file, you should tell the operating system you're done so that
it can clean things up (for example, most operating systems record the date and time at which a file was
last accessed). This is called closing the file, which we can
do with the close
method of the scanner:
scanner.close();
Alternatives for opening a file
In the zyBook you may have seen a slight variation on the strategy above. Instead of creating the Scanner from aFile
object, you can create the Scanner from an instance of FileInputStream
.
FileInputStream fis = new FileInputStream("story.txt"); Scanner scanner = new Scanner(fis);This accomplishes the same thing. The only subtle difference is that if there is an exception, it will occur on creating the
FileInputStream
instead of on creation of the Scanner.
In the zyBook, they also declare the more general type IOException
instead of
FileNotFoundException
. This makes no practical difference.