Download File

Document related concepts
no text concepts found
Transcript
File I/O (Input and Output)
Why use files?

Things stored in files are more permanent
than things stored in variables in
programs.
Say we have a file called
“poem.dat” on disk in some folder.
Mares eat oats
And does eat oats
And little lambs eat ivy.
File input

Recall how we performed input:
Scanner in = new Scanner( System.in );

What is the source of the input?
File input
Instead of this:
Scanner in = new Scanner( System.in );
We’ll use:
Scanner in = new Scanner( new FileInputStream("data.txt") );
File input
import java.io.FileInputStream;
import java.util.Scanner;
class MyIO {
public static void main ( String args[] ) throws Exception {
Scanner in = new Scanner( new FileInputStream("out.txt") );
//…
in.close();
}
}
File input
import java.io.FileInputStream;
import java.util.Scanner;
class MyIO {
public static void main ( String args[] ) throws Exception {
Scanner in = new Scanner( new FileInputStream("out.txt") );
//…
in.close();
}
}
We’ll use this simpler technique rather
than the more powerful and complicated
technique used in the text (the try-catch
block).
Revisiting the Scanner class

String next ( )


boolean nextBoolean ( )


Scans the next token of the input as a float.
int nextInt ( )


Scans the next token of the input as a double.
float nextFloat ( )


Scans the next token of the input into a boolean value and
returns that value.
double nextDouble ( )


Finds and returns the next complete token (i.e., typically “words”
separated by whitespace) from this scanner.
Scans the next token of the input as an int.
String nextLine ( )

Advances this scanner past the current line and returns the input
that was skipped.
Additional Scanner class methods

String next ( )
 Finds and returns the next
complete token (i.e., typically
“words” separated by
whitespace) from this scanner.

boolean hasNext ( )
 Returns true if this scanner has
another token in its input.

boolean nextBoolean ( )
 Scans the next token of the input
into a boolean value and returns
that value.

boolean hasNextBoolean ( )
 Returns true if the next token in
this scanner's input can be
interpreted as a boolean value
using a case insensitive pattern
created from the string
"true|false".

double nextDouble ( )
 Scans the next token of the input
as a double.

boolean hasNextDouble ( )
 Returns true if the next token in
this scanner's input can be
interpreted as a double value
using the nextDouble() method.
Additional Scanner class methods

float nextFloat ( )
 Scans the next token of the input
as a float.

int nextInt ( )
 Scans the next token of the input
as an int.

String nextLine ( )
 Advances this scanner past the
current line and returns the input
that was skipped.

boolean hasNextFloat ( )
 Returns true if the next token in
this scanner's input can be
interpreted as a float value using
the nextFloat() method.

boolean hasNextInt ( )
 Returns true if the next token in
this scanner's input can be
interpreted as an int value in the
default radix using the nextInt()
method.

boolean hasNextLine ( )
 Returns true if there is another
line in the input of this scanner.
SHOW THE CONTENTS OF A
FILE (IN A WINDOW)
Ex. Output contents of file to
screen/window.
//open the input file
Scanner in = new Scanner( new FileInputStream("poem.dat") );
//read one line from the input file
if (in.hasNextLine()) {
String s = in.nextLine();
System.out.println( s );
}
//read another line from the input file
if (in.hasNextLine()) {
String s = in.nextLine();
System.out.println( s );
}
…
in.close();
Ex. Output contents of file to
screen/window.
//open the input file
Scanner in = new Scanner( new FileInputStream("poem.dat") );
//read & write one line at a time
while ( in.hasNextLine() ) {
String s = in.nextLine();
System.out.println( s );
}
in.close();
Ex. Output contents of file to
screen/window.
//open the input file
Scanner in = new Scanner( new FileInputStream("poem.dat") );
//read & write one line at a time
for ( ; ; ) { //what will happen now?
String s = in.nextLine();
System.out.println( s );
}
//in.close();
//must do this
//otherwise, compiler will error w/
//unreachable statement
Ex. Output contents of file to
screen/window.
//open the input file
Scanner in = new Scanner( new FileInputStream("poem.dat") );
//read & write one line at a time
for ( ; ; ) { //what will happen now?
String s = in.nextLine();
System.out.println( s );
}
//in.close();
//must do this
Mares eat oats
//otherwise, compiler
will error
w/
And does
eat oats
//unreachable statement
And little lambs eat ivy.
Exception in thread "main"
java.util.NoSuchElementException: No line found
at java.util.Scanner.nextLine(Scanner.java:1471)
at FileIO.main(MyIO.java:13)
Ex. Output contents of file to
screen/window.
//open the input file
Scanner in = new Scanner( new FileInputStream("poem.dat") );
//read & write one line at a time
while ( in.hasNextLine() ) {
String s = in.nextLine();
So when reading from a file,
System.out.println( s );
we always need some end-of}
file (EOF) test.
in.close();
Ex. Output contents of file to
screen/window.
//open the input file
Scanner in = new Scanner( System.in );
//read & write one line at a time
while ( in.hasNextLine() ) {
String s = in.nextLine();
When reading from the
System.out.println( s );
keyboard under Windows, we
}
can indicate EOF by pressing
ctrl-D followed by Enter. (We
in.close();
can also press ctrl-C but that
aborts the program
immediately.)
WRITING TO FILES
File output

If we look at the definition of Java’s
System class, we see that System.out is of
type PrintStream.

To write to a file, we will use
FileOutputStream and PrintWriter.
File output

To write to a file, we will use FileOutputStream
and PrintWriter.
import java.io.FileOutputStream;
import java.io.PrintWriter;
class MyIO {
public static void main ( String args[] ) throws Exception {
System.out.println( "begin writing to a file" );
PrintWriter out = new PrintWriter( new FileOutputStream("out.txt") );
out.println( "hello fred." );
out.println( "and ethel." );
//close is required for files. if we forget, the file will be created
// but it will be empty!
out.close();
System.out.println( "done writing to a file" );
}
}
Writing to a file (file output)
//create a new, empty output file
PrintWriter out = new PrintWriter( new FileOutputStream("out.txt") );
//write something to the output file
out.println( "hello fred." );
out.println( "and ethel." );
//close is required for files.
// if we forget, the file will be created but it will be empty!
out.close();
Writing to a file (file output)
//create a new, empty output file
PrintWriter out = new PrintWriter( new FileOutputStream("out.txt") );
//write something to the output file
out.println( "hello fred." );
out.println( "and ethel." );
If the file already exists, it will be
erased and a new, empty output
file will be created. The old
contents, if any, will be lost.
//close is required for files.
// if we forget, the file will be created but it will be empty!
out.close();
Writing to a file (file output)
//create a new, empty output file
PrintWriter out = new PrintWriter( new FileOutputStream("out.txt“, true) );
//write something to the output file
out.println( "hello fred." );
out.println( "and ethel." );
This will cause new information
to be added at the end. The
original contents will not be lost.
//close is required for files.
This is called append mode.
// if we forget, the file will be created but it will be empty!
out.close();
The other, default mode is
called overwrite.
Writing to a file (file output)
//create a new, empty output file
PrintWriter out = new PrintWriter( new FileOutputStream("out.txt") );
//write something to the output file
out.println( "hello fred." );
out.println( "and ethel." );
//close is required for files.
// if we forget, the file will be created but it will be empty!
out.close();
Close is required because this is buffered I/O: “Rather than
physically writing every instance of output data as soon as
possible, the data is saved in a temporary location, known as a
buffer; when enough data is accumulated in this temporary
location, it is physically written to the file. This can add to
efficiency, since physical writes to a file can be slow.”
MAKING A COPY OF A FILE
So how do I write a program
to copy one file to another
file?
Copy one file to another
//declare vars & open input and output files
Scanner in = new Scanner( new FileInputStream("poem.dat") );
PrintWriter out = new PrintWriter(
new FileOutputStream("poem-copy.dat") );
Input file
//loop and copy all lines
Output file
while (in.hasNextLine()) {
String s = in.nextLine(); //read a line from input
out.println( s );
//write a line to output
}
out.close();
in.close();
CREATING A SECRET CODE
Creating a secret code

Problem: I keep my diary in a text file
called “diary.txt”. I think my little brother is
reading my diary. I’d like to encode it so
he can’t read it.
Creating a secret code

(algorithmic) steps:
1.
2.
3.
What should I call my program (class)?
Declare variables.
Repeat these steps:
1.
2.
3.
4.
Read in a line.
Encode a line.
Write the encoded line.
Finish up.
Creating a secret code

What is my secret code? How do I
encode things?

Consult Hollywood!
“2001” movie
 Computer called HAL.
 What was HAL really?

Creating a secret code
What is my secret code? How do I
encode things?
 Consult Hollywood!

“2001” movie
 Computer called HAL.
 What was HAL really?

 “HAL”
stands for “IBM” – they subtracted 1 from
each character.
 We’ll adopt the same technique and make ‘B’ into
‘A’ …
Encoding
//ch below is a char (a character)
char enc = ch; //no change by default
//encode the characters
if
(ch=='a')
enc = 'z';
else if (ch=='b')
enc = 'a';
else if (ch=='c')
enc = 'b';
…
else if (ch=='z')
enc = 'y';
Another way to encode

What statement (other than ‘if’) did we see
recently that can also be used for
encoding?
//ch below is a char (a character)
char enc = ch; //no change by default
//encode the characters
switch (ch) {
case 'a':
enc = 'z';
case 'b':
enc = 'a';
…
case 'z':
enc = 'y';
}
break;
break;
break;
//ch below is a char (a character)
char enc = ch; //no change by default
//encode the characters
switch (ch) {
case 'a':
enc = 'z';
case 'b':
enc = 'a';
…
case 'z':
enc = 'y';
}
Switch expressions must always
evaluate to integers. So how/why
does this work?
break;
break;
break;
ASCII = American Standard Code
for Information Interchange

The characters are assigned numbers
(integers).

So we can use them in a switch.

We can also add, subtract, multiply, and
divide them!
Given that, how can we make this
less cumbersome?
//ch below is a char (a character)
//ch below is a char (a character)
char enc = ch; //default = same
char enc = ch; //default = same
//encode the characters
if
(ch=='a')
enc = 'z';
else if (ch=='b')
enc = 'a';
else if (ch=='c')
enc = 'b';
…
//encode the characters
switch (ch) {
case 'a':
enc = 'z';
break;
case 'b':
enc = 'a';
break;
…
}
char enc;
if (ch=='a') {
enc = 'z';
} else if (ch>'a' && ch<='z') {
enc = (char)(ch-1);
} else {
enc = ch;
//unchanged
}
char enc;
if (ch=='a') {
enc = 'z';
} else if (ch>'a' && ch<='z') {
enc = (char)(ch-1);
} else {
enc = ch;
//unchanged
}
How about
uppercase letters?
char enc;
if (ch=='a') {
enc = 'z';
} else if (ch>'a' && ch<='z') { //handle lowercase letters
enc = (char)(ch-1);
} else if (ch=='A') { //handle uppercase letters
enc = 'Z';
} else if (ch>'A' && ch<='Z') {
enc = (char)(ch-1);
} else {
enc = ch; //unchanged
}
Casts
if (ch=='a') {
enc = 'z';
} else if (ch>'a' && ch<='z') {
enc = (char)(ch-1);
The result of this expression is
an int.
} else {
enc = ch;
//unchanged
}
cast = convert from other types
(int) to this type (char).
Other useful casts.
float f = (float)0.3;
int i = (int)12.6;

Causes truncation. What if I wanted to
round?
Casts and rounding
double d = 0.9;
int i1 = (int) d;
int i2 = (int) (d+0.5);
Back to our original problem:
How can we use this to encode our
diary?
Algorithm:
•What should I call my program (class)?
•Declare variables.
•Repeat these steps:
•Read in a line.
•Encode a line.
•Write the encoded line.
•Finish up.
char enc;
if (ch=='a') {
enc = 'z';
} else if (ch>'a' && ch<='z') {
enc = (char)(ch-1);
} else {
enc = ch; //unchanged
}
Recall: Output contents of file to
screen/window.
//open the input file
Scanner in = new Scanner( new FileInputStream("diary.txt") );
//read & write one line at a time
while ( in.hasNextLine() ) {
String s = in.nextLine();
//perform encoding
…
//output encoded line
System.out.println( s );
}
in.close();
//open the input file
Scanner in = new Scanner( new FileInputStream("diary.txt") );
//read & write one line at a time
while ( in.hasNextLine() ) {
String s = in.nextLine();
//perform encoding
char enc;
if (ch=='a') {
enc = 'z';
} else if (ch>'a' && ch<='z') {
enc = (char)(ch-1);
} else {
enc = ch;
//unchanged
}
//output encoded line
System.out.println( s );
}
in.close();
How can we get ch from
s?
//open the input file
Scanner in = new Scanner( new FileInputStream("diary.txt") );
//read & write one line at a time
while ( in.hasNextLine() ) {
String s = in.nextLine();
char ch = s.charAt( 0 );
//perform encoding
char enc;
if (ch=='a') {
enc = 'z';
} else if (ch>'a' && ch<='z') {
enc = (char)(ch-1);
} else {
enc = ch;
//unchanged
}
//output encoded line
System.out.println( s );
}
in.close();
How can we get all of the
chars from s?
//open the input file
Scanner in = new Scanner( new FileInputStream("diary.txt") );
//read & write one line at a time
while ( in.hasNextLine() ) {
String s = in.nextLine();
Now we need to create an
for (int i=0; i<s.length(); i++) {
output string of encoded
char ch = s.charAt( i );
chars.
//perform encoding
char enc;
if (ch=='a') {
enc = 'z';
} else if (ch>'a' && ch<='z') {
enc = (char)(ch-1);
} else {
enc = ch;
//unchanged
}
}
System.out.println( s ); //output encoded line
}
//read & write one line at a time
while ( in.hasNextLine() ) {
String s = in.nextLine();
String outLine = "";
for (int i=0; i<s.length(); i++) {
char ch = s.charAt( i );
We created an output
//perform encoding
string of encoded chars.
char enc;
if (ch=='a') {
Finally, we need to write
enc = 'z';
out the encoded
} else if (ch>'a' && ch<='z') {
enc = (char)(ch-1);
information to another file.
} else {
enc = ch;
//unchanged
}
outLine = outLine + enc;
}
System.out.println( outLine ); //output encoded line
}
Here’s the complete program that writes the encoded
information to another file.
Don’t forget that you need a decoder program too!
import
import
import
import
java.io.FileInputStream;
java.io.FileOutputStream;
java.io.PrintWriter;
java.util.Scanner;
//perform encoding
char enc;
if (ch=='a') {
enc = 'z';
} else if (ch>'a' && ch<='z') {
enc = (char)(ch-1);
} else if (ch=='A') { //handle uppercase letters
enc = 'Z';
} else if (ch>'A' && ch<='Z') {
enc = (char)(ch-1);
} else {
enc = ch;
//unchanged
}
outLine = outLine + enc;
class Encode {
public static void main ( String args[] ) throws
Exception {
//open the input file
Scanner in = new Scanner( new
FileInputStream("diary.txt") );
//open the output file
PrintWriter out = new PrintWriter( new
FileOutputStream("out.txt") );
//read & write one line at a time
while ( in.hasNextLine() ) {
String s = in.nextLine();
String outLine = "";
System.out.println( "read: " + s );
for (int i=0; i<s.length(); i++) {
char ch = s.charAt( i );
}
out.println( outLine ); //output encoded line
}
out.close();
in.close();
}
}
TYPES OF FILES
Types of files

Text





only contains lines of ASCII text
can be viewed with text editors such as notepad
easier to work with but less compact
used in this course
Binary



very compact but you have to be privy to the format
cannot be viewed with text editors
not used in this course
ANOTHER PROBLEM FOR
DISCUSSION
Problem for discussion



You did a survey. You have a file containing
numbers (integers) from a survey. Valid
responses are in the range [1..10].
Write a program that reads in these numbers
and determines their average.
You may assume that the file only contains
integers but some responses may not be valid
(e.g., 0, -5, or 100). You should not include
these values in the average. However, you
should print a message like the following:

Response number 22 is invalid, -7.
YET ANOTHER PROBLEM FOR
DISCUSSION
Yet another problem for
discussion




You did another survey (of ages of people who
voted in the last election).
You keep the ages in a file.
What is the min, max, and mean voting age?
For extra credit, what is the mean voting age if you
don’t count the min and max? (This is called the
trimmed or truncated mean,
http://en.wikipedia.org/wiki/Truncated_mean, or
the interquartile mean,
http://en.wikipedia.org/wiki/Interquartile_mean.)