Transcript Chapter 9

Chapter 9-Text File I/O
Overview






Text File I/O and Streams
Writing to a file.
Reading from a file.
Parsing and tokenizing.
Random Access
Review.
Streams/ Text File I/O
Why File I/O?



Users rarely do all of their computing in
one sitting. Even if they do finish, they
want to save the results.
In all of our programs so far, the results
are lost when our program ends.
If we use file I/O, we can save
information for future use, read in setup
information, etc.
What are streams?



Streams are basically just data that is
waiting for processing.
They can be used for file I/O, network
I/O, and any other way that two
programs might want to communicate
with each other.
We have been using Streams whenever
we output to the screen or take in from
the keyboard.
Using streams.


When we System.out.println a string,
that string is written to an output stream.
When the computer is ready, that
stream is flushed out to the monitor.
When we type things as input into the
keyboard, it goes into an input stream.
SavitchIn then reads from this stream
when we want input from the user.
Text I/O vs. Binary I/O



The book describes two kinds of I/O,
only one of which we will be covering.
Text I/O writes out information to a file in
such a way that we can read it with a
standard text editor like Notepad or
Word.
Binary I/O writes things out in merely 1’s
and 0’s and is usually not easily
readable by humans.
When using I/O

When using any of the file I/O methods
or classes you will want to include the
java.io library.
import java.io.*;
Writing to a file.
Writing to a file


We will first look at writing information to
a text file, since it is easier than reading.
The first thing that we need to do is
open a file. We do this by creating a
PrintWriter object.
PrintWriter output = new PrintWriter(
new FileOutputStream(“Somefile.txt”));
Streams and output files

Java has a bunch of I/O streams, and
we often need to layer these for doing
I/O operations. You can do it in separate
steps or in a single one.
FileOutputStream a = new FileOutputStream(
“Somefile.txt”);
PrintWriter output = new PrintWriter(a);
Or
PrintWriter output = new PrintWriter(
new FileOutputStream(“Somefile.txt”));
More on opening files


The PrintWriter is an output stream that
allows for the usual kind of output we
are used to doing with a console.
When opening any file(reading or
writing), you will need to be able to
catch the FileNotFoundException that
can be thrown if the file requested does
not exist. Use try and catch blocks.
The delicate exposition of
nonexistence...


Now that we have the file open, we can
write to it at our leisure.
Instead of writing strings to the console
with System.out.println(“Hello”), we now
replace System.out with “output” (or the
name of our stream).
output.println(“Hello”);
Writing other types

We can write anything we could write to
the screen. Integers, doubles, anything.
int I = 5;
double j = 4.0;
output.println(“This is a number: “ + I);
//Writes “This is a number: 5\n” to Somefile.txt
output.println(“So is this: “ +4.0);
//Writes “So is this: 4.0\n” to Somefile.txt
Always put things back the way
you found them.


When you are finished writing to your
file, you want to close it. If you don’t
close it, someone else that needs the
file may not be able to open it.
If you don’t close it, Java will close it for
you when your program ends normally(if
it ends normally).
output.close();
Notes about basic writing.



Can also use the print(String) function
to print without an automatic new line.
When you open a file for writing, any
current contents of the file are erased.
You can also open a file in append
mode if you would like.
Opening in append mode

Append mode just means the file opens
pointing at the end of the file as
opposed to the beginning.
PrintWriter a = new PrintWriter(new
FileOutputStream(“Somefile”, true));
Says to append(omit or use
false to just overwrite)
Reading from a file.
Reading from a file.



Writing to a file is nice, but eventually
we will probably want to retrieve that
information back into the Java program.
So we need the ability to read from files.
Reading strings is easy. Reading other
types is hard (just like with console
input, except there is no SavitchIn to
use as a shortcut).
Opening a file for reading.

Again we will layer streams, but this
time we use input readers.
BufferedReader input = new BufferedReader(
new FileReader(“Somefile.txt”));
Reading Strings from files...

Once you have opened the file, you can
use readLine() to read in the next newline delimited string.
String a = input.readLine();
When there are no strings left.

When you have already read all of the
strings in the file, readLine() will return
the value null, so you should always test
for this before using the string.
String a = input.readLine();
if(a != null)
System.out.println(a);
Close the file

Just like when writing, we should close
the file when we are done with it. Looks
the same too.
input.close();
That’s great, but what about nonstrings?



When we use readLine(), we are returned a
line of information as a String.
This line can have all kinds of info inside of it:
integers, doubles, characters, booleans,
objects(possibly).
To retrieve this information, we need to parse
the string given to us by readLine().
Parsing and tokenizing
Parsing- What is it?


The general idea of parsing is to find all
the useful information that we want that
is contained in a String.
Thus in the string:
3 + 4 \n
we might want the 3, the 4, and the +
operator, but not the spaces and the
new line.
Parsing- the simple case

If we have a string that merely has a
single piece of data in it, then we can
use the parse method of the wrapper
class.
String s = “3.40”;
int I = Integer.parseInt(“5”); //I=5
double D = Double.parseDouble(s);//D=3.40
Parsing exceptions

Any time you use one of the number
parsing methods, you will need to be
ready to catch a
NumberFormatException.
Parsing types
IntegersDoublesFloatsLongsBooleans-
Integer.parseInt(String);
Double.parseDouble(String);
Float.parseFloat(String);
Long.parseLong(String);
Boolean.valueOf(String);
//true if “true”
//false otherwise.
Characters- String.charAt(int);
//”Hello”.charAt(0) = ‘H’
It’s not always that simple...




Unfortunately, all of those parsing methods
required that the data be the only thing in the
string.
Often the Strings returned by readLine() have
more info than we need.
We need a way to break the big string
returned by readLine() into smaller strings
that each have just one piece of data in them.
This is tokenizing.
StringTokenizer class


The StringTokenizer class is located in
java.util, so you will need to import java.util.*
or java.util.StringTokenizer.
When you create a StringTokenizer object,
you give it the string you want to break up into
pieces.
StringTokenizer blar = new
StringTokenizer(“This is some stuff”);
StringTokenizer



The default way for a StringTokenizer to
break up a word is by whitespace.
We can tell how many pieces are left in the
string by calling countTokens() or just see if
there are more by using hasMoreTokens().
We get the next chunk by calling nextToken().
while(blar.hasMoreTokens())
{
System.out.println(blar.nextToken())
}
Getting tokens
while(blar.hasMoreTokens())
{
System.out.println(blar.nextToken());
}
This
is
some
stuff
StringTokenizer details



You should always make sure there are more
tokens available before trying to get one. If
there aren’t any left, the method will throw an
exception and likely crash your program.
You can use different delimiters than
whitespace if you want to. See the Java
documentation on how to do that.
You can also have the delimiters themselves
be returned as separate tokens. Again see
the documentation.
Random Access
RandomAccessFile


If you are used to the old way of dealing
with files (read, write, seek), you can
still do this with RandomAccessFile.
RandomAccessFile allows you to both
read and write inside a file. You can also
skip back and forth through the file to
find what you want.
Opening and closing
RandomAccessFiles
RandomAccessFile file = new
RandomAccessFile(“Something.txt”, “rw”);
//opened for read-write access.
//could also just use “r” for read access.
...
file.close();
Other useful functions inside of
RandomAccessFile



You can read(), readLine(), readInt(),
readDouble(),readChar(),readBoolean().
You can get the length() of a file, or
seek(long) to a position.
Writing is not as easy:
writeDouble(double), writeInt(int),
writeBoolean(boolean),
writeBytes(String), writeChars(String).
When to use RandomAccessFile


We don’t usually want to use this class,
unless you just need to slightly modify a
file.
Usually want to use two separate files,
one for reading, and one for writing.
Most examples I have seen in the books
are used this way.
Review
File I/O Review



What do we have to import to be able to do
file I/O?
What do we have to import to do tokenizing?
What do we have to import to use the parse
methods of the primitive wrappers
(Double.parseDouble(String)…)?