We already know much of what we need for reading and writing files of text (characters). For input, we use the Scanner class, and for output we use the print() and println() methods.
We have previously constructed an instance of class Scanner from the existing input stream System.in. To open an existing file as a character stream, we instantiate the class FileInputStream, from which we can then create a Scanner.
To write to a file, we create an instance of PrintWriter, giving it the name of the file we want to write. Warning: Doing this will overwrite the file, deleting whatever was already in it. So be careful about what you open in this way.
Whenever we open a file, we should be careful to close it. Both Scanner and PrintWriter provide a method close().
Note that the declarations of the constructors for FileInputStream and PrintWriter include a clause throws FileNotFoundException. Note that both this exception and its slightly more general supertype IOException belong to java.io; so you will have to either import these names or use a qualified name.
It is also possible that reading or writing an open file will throw an IOException, although the Scanner and PrintWriter classes will not do that. If you operate more directly on an open file, you will need to do the reading or writing inside a try with an appropriate catch clause. The reason may not be obvious to you, but the close() method can also throw an IOException.
For programs that are not trivial, it is important to remember to close any file that you open. A good way to do that is to wrap the code that processes the file in a try...finally. What this means in practice is that file processing usually looks something like this:
You would treat a PrintWriter in a manner similar to the way the Scanner is handled above.