chapter16

chapter16 - Chapter 16 Files and Streams Goals To be able...

Info iconThis preview shows page 1. Sign up to view the full content.

View Full Document Right Arrow Icon
This is the end of the preview. Sign up to access the rest of the document.

Unformatted text preview: Chapter 16 Files and Streams Goals 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 To be able to read and write objects using serialization keyboard standard input stream CPU standardo utput stream MEM monitor terminal console What does information travel across? Streams HDD keyboard standard input stream CPU standardo utput stream file input stream LOAD READ MEM monitor terminal console What does information travel across? HDD files file output stream SAVE WRITE Streams Reading and Writing Text Files Text files files containing simple text Created with editors such as notepad, html, etc. Simplest way to learn it so extend our use of Scanner Associate with files instead of System.in All input classes, except Scanner, are in java.io import java.io.*; Review: Scanner We've seen Scanner before The constructor takes an object of type java.io.InputStream stores information about the connection between an input device and the computer or program Recall only associate one instance of Scanner with System.in in your program Example: System.in Otherwise, get bugs 2 ways (we've learned one, seen the other) Numerical Input Use int as example, similar for double First way: Use nextInt() int number = scanner.nextInt(); Second way: Use nextLine(), Integer.parseInt() String input = scanner.nextLine(); int number = Integer.parseInt(input); Numerical Input Exceptions nextInt() throws InputMismatchException parseInt() throws NumberFormatException Optimal use nextInt() when there is multiple information on one line nextLine() + parseInt() when one number per line Reading Files The same applies for both console input and file input We can use a different version of a Scanner that takes a File instead of System.in Everything works the same! Reading Files To read from a disk file, construct a FileReader Then, use the FileReader to construct a Scanner object FileReader rdr = newFileReader("input.txt"); Scanner fin = new Scanner(rdr); Reading Files You can use File instead of FileReader Has an exists() method we can call to avoid FileNotFoundException File file = new File ("input.txt"); Scanner fin; if(file.exists()){ fin = new Scanner(file); } else { //ask for another file } Reading Files Once we have a Scanner, we can use methods we already know: next, nextLine, nextInt, etc. Reads the information from the file instead of console File Class java.io.File associated with an actual file on hard drive used to check file's status Constructors File(<full path>) File(<path>, <filename>) exists() canRead(), canWrite() isFile(), isDirectory() Methods File Class java.io.FileReader Associated with File object Translates data bytes from File object into a stream of characters (much like InputStream vs. InputStreamReader) FileReader( <File object> ); Constructors Methods read(), readLine() close() Writing to a File We will use a PrintWriter object to write to a file What if file already exists? Empty file Doesn't exist? Create empty file with that name How do we use a PrintWriter object? Have we already seen one? Writing to a File The out field of the System class is a PrintWriter object associated with the console We will associate our PrintWriter with a file now PrintWriter fout = new PrintWriter("output.txt"); fout.println(29.95); fout.println(new Rectangle(5, 10, 15, 25)); fout.println("Hello, World!"); This will print the exact same information as with System.out (except to a file "output.txt")! Closing a File Only main difference is that we have to close the file stream when we are done writing If we do not, not all output will written At the end of output, call close() fout.close(); Closing a File Why? When you call print() and/or println(), the output is actually written to a 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 Locations When determining a file name, the default is to place in the same directory as your .class files If we want to define other place, use an absolute path (e.g. c:\My Documents) Why \\ ? in = new FileReader("c:\\homework\\input.dat"); Sample Program Two things to notice: Have to import from java.io I/O requires us to catch checked exceptions java.io.IOException Java Input Review CONSOLE: Scanner stdin = new Scanner( System.in ); FILE: Scanner inFile = new Scanner( new FileReader(srcFileName )); Java Output Review CONSOLE: System.out.print("To the screen"); FILE: PrintWriter fout = new PrintWriter(new File("output.txt"); fout.print("To a file"); import import import import java.io.FileReader; java.io.IOException; java.io.PrintWriter; java.util.Scanner; public class LineNumberer{ public static void main(String args){ Scanner console = new Scanner(System.in); System.out.print("Input file: "); String inFile = console.next(); System.out.print("Output file: "); String outFile = console.next(); try{ FileReader reader = new FileReader(inFile); Scanner in = new Scanner(reader); PrintWriter out = new PrintWriter(outputFileName); int lineNumber = 1; while (in.hasNextLine()){ String line = in.nextLine(); out.println("/* " + lineNumber + " */ " + line); lineNumber++; } out.close(); } catch (IOException exception){ System.out.println("Error processing file: " + exception); } } } 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, 128bit encryption breaking, etc.) Modifications of Output Two constraints so far: Files are overwritten Output is buffered and not written immediately We have options to get around this File Class java.io.FileWriter Associated with File object Connects an output stream to write bytes of info Constructors FileWriter( <filename>, <boolean> ); true to append data, false to overwrite all of file This will overwrite an existing file To avoid, create File object and see if exists() is true Java File Output PrintWriter composed from several objects PrintWriter out = new PrintWriter( new FileWriter( dstFileName, false requires throws FileNotFoundException, which is a sub class of IOException ), true ); Methods print(), println(): buffers data to write close(): flushes and closes stream flush(): sends buffered output to destination Java File Output // With append to an existing file PrintWriter outFile1 = new PrintWriter( new FileWriter(dstFileName,true),false); // With autoflush on println PrintWriter outFile2 = new PrintWriter( new FileWriter(dstFileName,false),true); outFile1.println( "appended w/out flush" ); outFile2.println( "overwrite with flush" ); To flush or not to flush Advantage to flush: Safer guaranteed that all of our data will write to the file Disadvantage Less efficient writing to file takes up time, more efficient to flush once (on close) Caeser Cipher Encryption key the function to change the value Simple key shift each letter over by 1 to 25 characters If key = 3, A D B E etc. Decryption = reversing the encryption Here we just subtract the key value Binary File Encryption int next = in.read(); if (next == -1) done = true; else { byte b = (byte) next; //call the method to encrypt the byte byte c = encrypt(b); out.write(c); } Object Streams Last example read BankAccount field individually ObjectOutputStream class can save a entire Easier way to deal with whole object objects to disk ObjectOutputStream class can read objects back in from disk Objects are saved in binary format; hence, you use streams and not writers Write out an object The object output stream saves all instance variables BankAccount b = . . .; ObjectOutputStream out = new ObjectOutputStream( new FileOutputStream("bank.dat")); out.writeObject(b); Read in an object readObject returns an Object reference Need to remember the types of the objects that you saved and use a cast ObjectInputStream in = new ObjectInputStream( new FileInputStream("bank.dat")); BankAccount b = (BankAccount) in.readObject(); Exceptions readObject method can throw a ClassNotFoundException It is a checked exception You must catch or declare it Writing an Array Usually want to write out a collection of objects: BankAccount arr = new BankAccount[size]; // Now add size BankAccount objects into arr out.writeObject(arr); Reading an Array To read a set of objects into an array BankAccount ary = (BankAccount) in.readObject(); Object Streams Very powerful features Especially considering how little we have to do The BankAccount class as is actually will not work with the stream Must implement Serializable interface in order for the formatting to work Object Streams class BankAccount implements Serializable { . . . } IMPORTANT: Serializable interface has no methods. No effort required Serialization Serialization: process of saving objects to a stream Each object is assigned a serial number on the stream If the same object is saved twice, only serial number is written out the second time When reading, duplicate serial numbers are restored as references to the same object Serialization Why isn't everything serializable? Security reasons may not want contents of objects printed out to disk, then anyone can print out internal structure and analyze it Example: Don't want SSN ever being accessed Could also have temporary variables that are useless once the program is done running Often several text values are in a single line in a file to be compact "25 38 36 34 29 60 59" The line must be broken into parts (i.e. tokens) "25" "38" "36" tokens then can be parsed as needed "25" can be turned into the integer 25 Tokenizing Tokenizing Inputting each value on a new line makes the file very long May want a file of customer info name, age, phone number all on one line File usually separate each piece of info with a delimiter any special character designating a new piece of data (space in previous example) Tokenizing in Java use a StringTokenizer object default delimiters are: space, tab, newline, return requires: import java.util.* Constructors StringTokenizer(String StringTokenizer(String line)//default dlms ln, String dlms) Methods hasMoreTokens() nextToken() countTokens() StringTokenizing in Java Scanner stdin = new... System.out.print( "Enter a line with comma seperated integers(no space): " ); String input = stdin.nextLine(); StringTokenizer st; String delims = ","; st = new StringTokenizer( input, delims ); while ( st.hasMoreTokens() ) { int n = Integer.parseInt(st.nextToken()); System.out.println(n); } File gradeFile = new File("scores.txt"); if(gradeFile.exists()){ Scanner inFile = new Scanner(gradeFile); String line = inFile.nextLine(); while(line != null){ StringTokenizer st = new StringTokenizer(line, ":"); System.out.print(" Name: " + st.nextToken()); int num = 0; double sum = 0; while ( st.hasMoreTokens() ) { num++; sum += Integer.parseInt(st.nextToken()); } System.our.println(" average = "+ sum/num); line = inFile.nextLine(); } inFile.close(); } If you call nextToken() and there are no more tokens, NoSuchElementException is thrown Tokenizing Scanner tokenizes already... Scanner in = new Scanner(...); while(in.hasNext()) { String str = in.next(); ... } ...
View Full Document

This note was uploaded on 08/08/2008 for the course CS 302 taught by Professor Willbenton during the Spring '07 term at Wisconsin.

Ask a homework question - tutors are online