Announcements
Chapter 16 – Files and Streams
Only responsible for 16.1,16.3
Other sections “encouraged” encouraged”
Responsible for online supplements for Exceptions and File I/O (see syllabus)
keyboard standard input stream
Chapter Goals
CPU
To be able to read and write text files To become familiar with the concepts of text and binary formats To learn about encryption To understand when to use sequential and random file access
standard output stream
monitor terminal console
MEM
HDD
What does information travel across? Streams
keyboard standard input stream
16.1 Reading and Writing Text Files CPU
monitor terminal console
standard output stream
file input stream LOAD What does information READ
MEM
Created with editors such as notepad, etc.
Simplest way to learn it so extend our use of Scanner
HDD
travel across?
Streams
Text files – files containing plain text
files
file output stream SAVE WRITE
Associate with files instead of System.in
All input classes, except Scanner, are in java.io
import java.io.*; java.io.*;
1
Review: Numerical Input
Review: Scanner
Two ways to use scanner two constructors First constructors takes an object of type java.io.InputStream – stores information about the connection between an input device and the computer or program
First way: Use nextInt() nextInt() int number = scanner.nextInt(); scanner.nextInt();
Second way: Use nextLine(), nextLine(), Integer.parseInt() Integer.parseInt() String input = scanner.nextLine(); scanner.nextLine(); int number = Integer.parseInt(input); Integer.parseInt(input);
Example: System.in
Recall – only associate one instance of Scanner with System.in in your program
What’ What’s the difference?
Exceptions
Reading
nextInt() nextInt() throws InputMismatchException
parseInt() parseInt() throws NumberFormatException
FileReader
Optimal use
nextInt() nextInt() when multiple information on one line
nextLine() nextLine() + parseInt() parseInt() when one number
To read from a disk file, construct a
Then, use the FileReader to construct a Scanner object
FileReader reader = new FileReader("input.txt"); FileReader("input.txt"); Scanner in = new Scanner(reader); Scanner(reader);
per line
Alternative
Use File instead of FileReader
What does this do?
Has an exists( ) method we can call to avoid FileNotFoundException
File file = new File ("input.txt "); ("input.txt"); Scanner in; if(file.exists()){ if(file.exists()){ in = new Scanner(file); Scanner(file); } else { //ask for another file }
Allows us to use methods we already know
next, nextLine, nextLine, nextInt, etc.
Reads the information from the file instead of console
2
File Class
java.io.File associated with actual file on hard drive used to check file's status
What if file already exists? Empty file (delete whatever is there) Doesn’ Doesn’t exist? Create empty file with that name
File(), path>), File(, )
Predicate Methods
exists() canRead() canRead(),, canWrite() canWrite() isFile() isFile(),, isDirectory() isDirectory()
Have we already seen one? Almost.
Closing File
The out field of System is a PrintStream object associated with the console. PrintWriter is a similar class optimized for writing characters.
How do we use a PrintWriter object?
PrintWriter
We will use a PrintWriter object to write to a file
Constructors
Writing To File
We will associate our PrintWriter with a file now Can use either a filename or File object
PrintWriter fileOut = new PrintWriter("output.txt"); PrintWriter("output.txt"); fileOut.println(29.95); fileOut.println(new Rectangle(5, 10, 15, 25));
Only difference is that we have to close the file stream when we are done writing
If we do not, some output may not get written
At the end of output, call close()
fileOut.println("Hello, fileOut.println("Hello, World!");
This will print the exact same information as with System.out (except to a file “output.txt” output.txt”)!
fileOut.close(); fileOut.close();
Why?
Short answer When you call print( ) and/or println( println( ), the output is actually written to buffer. When you close or flush the output, the buffer is written to the file The slowest part of the computer is hard drive operations – much more efficient to write once instead of writing repeated times
File name
When determining a file name, default is to place in the same directory as your .class files
If we want to define other place, use absolute path (e.g. C:\ C:\My Documents)
in
= new FileReader(“ FileReader(“C:\ C:\\homework\ homework\\input.dat” input.dat”);
3
Getting it all to work
Java Input Review CONSOLE:
Remember:
Have to import from java.io I/O requires us to catch checked exceptions
Scanner stdin = new Scanner( System.in );
java.io.IOException
FILE:
How long do we read from the file?
Until the end. (duh) Use the hasNext( ), hasNextLine( ) and hasNextInt( ) predicate methods from Scanner. Otherwise
import import import import
Scanner inFile = new Scanner( new File ( srcFileName ) );
you risk creating a NoSuchElementException
try{ File reader = new File(inFile); File(inFile); Scanner in = new Scanner(reader); Scanner(reader); PrintWriter out = new PrintWriter(outputFileName); PrintWriter(outputFileName); int lineNumber = 1; while (in.hasNextLine ()){ (in.hasNextLine()){ String line = in.nextLine(); in.nextLine(); out.println("/* out.println("/* " + lineNumber + " */ " + line); lineNumber++; lineNumber++; } out.close(); out.close(); } catch (IOException (IOException exception){ System.out.println("Error processing file: " + exception.getMessage()); exception.getMessage()); } }
java.io.FileReader; java.io.FileReader; java.io.IOException; java.io.IOException; java.io.PrintWriter; java.io.PrintWriter; java.util.Scanner; java.util.Scanner;
public class LineNumberer { public static void main(String[] main(String[] args){ args){ Scanner console = new Scanner(System.in); Scanner(System.in); System.out.print(“ System.out.print(“Enter input file: "); String inFile = console.next(); console.next(); System.out.print(“ System.out.print(“Enter output file: "); String outFile = console.next(); console.next();
}
Common Error
Buffering gone bad
You can run into problems using nextLine( nextLine( ) in conjunction with nextInt( nextInt( ) from the Scanner class. 77 hello In order to read this file You typed this code, but got this output
int I = input.nextInt(); input.nextInt(); String s = input.nextLine(); input.nextLine(); System.out.println(i+” System.out.println(i+”,”+s); +s);
77,
To Java, the file is a long buffer of characters nextInt removes the characters corresponding to a number, and that’ that’s all. nextLine looks for the next newline character (‘ (‘\n’), and returns everything before the first one it finds, even if that String is empty!
7 7 \n h e l \n h e l
l
l
…
o \n …
i = 77
h e
l
l
o \n
…
s = “”
What went wrong?
4
What to do?
Avoid using nextInt( nextInt( ) and nextLine( nextLine( ) in combination Always use nextLine( nextLine( ) and convert to integers using Integer.parseInt( Integer.parseInt( ) Use nextInt( nextInt( ) in conjunction with next( ), which will skip over newlines to find the next nonnon-whitespace string
16.3 An Encryption Program
Demonstration: Use encryption to show file techniques
File encryption
To scramble a file so that it is readable only to those who know the encryption method and secret keyword (Big area of CS in terms of commercial applications – biometrics, ee-commerce, etc.)
Check to see if Strings from nextLine( nextLine( ) have length 0, and if so, call it again.
Caesar Cipher
Encryption key – the function to change the value Simple key – shift each letter over by 1 to 25 characters
Decrypt = reverse the encryption
If key = 3, A D B E etc. Here we just subtract the key value
Caesar Cipher for alphabetic characters public void encrypt (Scanner in, PrintWriter out, int key) { while (in.hasNextLine ()) { (in.hasNextLine()) String line = in.nextLine(); in.nextLine(); String outLine = “”; “”; for (int ; i++) { (int i=0; i