310 likes | 343 Views
File IO in Java. File FileReader / FileWriter Scanner / PrintWriter. What We Won’t Do. FileInputStream FileOutputStream These classes are for reading streams of raw data They are most often used for images Allows you to read bytes (in binary) We will focus on characters. Packages.
E N D
File IO in Java File FileReader / FileWriter Scanner / PrintWriter
What We Won’t Do • FileInputStream • FileOutputStream • These classes are for reading streams of raw data • They are most often used for images • Allows you to read bytes (in binary) • We will focus on characters
Packages • We’ll find the classes we’re using in the io and util packages: • import java.io.*; • import java.util.*;
File Class • Constructor: • File file = new File("c:\\data\\input.txt"); • Use the full or relative path (from current directory) • Here are some useful methods: • boolean fileExists = file.exists(); • int length = file.length(); //length in bytes • boolean success = file.renameTo(new File("c:\\data\\new.txt")); • boolean success = file.delete(); • File file = new File("c:\\data"); //can also be a directory boolean isDirectory = file.isDirectory(); • File file = new File("c:\\data"); String[ ] fileNames = file.list(); File[ ] files = file.listFiles();
try... catch blocks • In Java there is structure known as the try catch block. • Objects can throw an exception when something goes wrong to notify the user • Index out of bounds is one • This prevents programs from an all out crash since the code that would cause the problem is never executed
try... catch • Example: public void mustBeOdd(int number) throws Exception { if( number % 2 != 0 )//not even!!! throw Exception; //at this point the code is only executed if even statements… }
try… catch • Since the method declares the keyword throws anyone that uses the method must catch it in case of an error • So we tell Java we’re going to try to do something, but if an exception is thrown, we will catch it and deal with the error.
try… catch • Files can have all sorts of things go wrong • They might be read only and you try to write • They might be in use and not allow more than one person to read from them • They may no longer exist (could have been delete) • … • Most file I/O requires a try/catch block
FileReader • Reading each character in a file one at a time with FileReader: File test = new File("C:\\test.txt"); try { FileReader fr = new FileReader(test); int data = fr.read(); int counter = 1; while(data != -1) { System.out.println("Character #" + counter + " is " + (char)data); data = fr.read(); counter++; } fr.close();//close the file } catch(IOException e) { System.out.println(e); }
FileReader • Reading all characters at once with FileReader: File test = new File("C:\\test.txt"); try { FileReader fr = new FileReader(test); char[] allAtOnce = new char[(int)test.length()]; int charsRead = fr.read(allAtOnce); System.out.println("This file has " + test.length() + " bytes"); System.out.println("Here they are!"); System.out.println(allAtOnce); fr.close();//close the file } catch(IOException e) { System.out.println(e); }
FileReader • Reading all characters at once into an array is OK for small files • Large files may take up too much memory • This will eat up the computers resources • Can affect performance too! • The read method has two other versions: • read(char[] buffer) • Fills the array as much as possible from the files contents • read(char[] buffer, int startIndex, int length) • Fills the array starting at the position given for the number of characters specified
FileReader • Reading several characters at once with FileReader: File test = new File("C:\\Documents and Settings\\Cam\\Desktop\\test.txt"); try { FileReader fr = new FileReader(test); int amount = 25; char[] severalChars = new char[amount]; int charsRead = fr.read(severalChars); String allChars = new String(); while( charsRead != -1 ) { allChars += new String(severalChars);//create a string from the chars charsRead = fr.read(severalChars); } System.out.println("File says:"); System.out.println(allChars); fr.close();//close the file } catch(IOException e) { System.out.println(e); }
FileWriter • Writing to a file is similar • Some things to note when you open a file for writing: • If the file does not exist, it will be created for you • If the file does exist the contents are erased, the content you write becomes the new file • To avoid losing all the old information, you must either read the file first and save its contents to an array or use the append method • To write a new line like you expect, \n is not enough for a text file, you must use a carriage return also (\r): \r\n See example next slide
FileWriter • Writing a 10x10 multiplication table to a file: File test = new File("C:\\test.txt"); try { FileWriter fw = new FileWriter(test); for( int n = 1; n <= 10; n++ ) { for( int k = 1; k <= 10; k++) fw.write(n*k + "\t"); fw.write("\r\n"); } fw.close(); } catch(IOException e) { System.out.println(e); }
FileWriter • Appending a 10x10 multiplication table to a file: File test = new File("C:\\test.txt"); try { FileReader old = new FileReader(test); char[] oldData = new char[(int)test.length()]; old.read(oldData);//save old information old.close(); FileWriter fw = new FileWriter(test); fw.write(oldData);//put old data back so we can append new data for( int n = 1; n <= 10; n++ ) { for( int k = 1; k <= 10; k++) fw.write(n*k + "\t"); fw.write("\r\n"); } fw.close(); } catch(IOException e) { System.out.println(e); }
Not Much Help… • The FileReader and FileWriter class do what they say (read/write) but they don’t really have any additional features. • For example, what if you wanted to read a word at a time or maybe a whole line? • What if you wanted to read the data as an int instead of a char? • What if you wanted to print a line of text? • … • Let’s take a look at two classes that will help us • Scanner • PrintWriter
Scanner • The Scanner class works the same way as you know of it from reading console input • The stream is the only thing that changes • Instead of reading from the console, now we want the scanner to read from a file
Scanner Example • This example reads each “word” (string separated by white space) from a file and prints them one line at a time: File test = new File("C:\\test.txt"); try { FileReader read = new FileReader(test); Scanner in = new Scanner( read ); while( in.hasNext() )//is there something to read? System.out.println(in.next());//next method gets a word read.close(); } catch(IOException e) { System.out.println(e); }
Scanner Methods • The Scanner class is LOADED with methods for reading a stream: • hasNextInt(): next value is an int • hasNext(): next value is a string • hashNextLine(): there is another line of text to read • There are many to check what’s left in the file • next(): reads a token (separated by white space) • nextLine(): reads a line of text • nextInt(): reads the next token as an int • … • All of the next____() methods we’ve used to get data from the console can be used on a file
PrintWriter • The PrintWriter class behaves more like System.out • You can print just about any data type or object with a toString method into a file • You can also use the println method rather than having to use \r\n • The advantage is you can work with more than just chars and not have to worry about casting/conversions
Person Class public class Person { public Person( String name, int age ) public String toString() { return name + “\t” + age; } }
PrintWriter Example • This example prints an array of objects to a file: File test = new File("C:\\Documents and Settings\\Cam\\Desktop\\test.txt"); try { FileWriter fw = new FileWriter(test); PrintWriter writer = new PrintWriter( fw ); Person[ ] pArr = {new Person("John", 10), new Person("Bob", 12), new Person("Sue", 11), new Person("Anne", 13) }; for( int n = 0; n < pArr.length; n++ ) writer.println(pArr[n]);//Uses Person's toString method to print fw.close(); } catch(IOException e) { System.out.println(e); }
Exercises - FileUtility • The first class we’ll create will be called FileUtility • The class takes a path to a file in its constructor and performs the following tasks (methods): • public int wordCount() • Returns the number of words in the file • public int lineCount() • Returns the number of lines in the file • public int count(String word) • Returns the number of instances of word in the file • public void replace(String target, String replacement) • Should work for all instances, not just whole words • Ex. replace( “ing”, “abc” ) turns “flying” to “flyabc” in the file • public void append( String data ) • Appends data to the end of the file
Exercises - FileUtility • The last 4 methods are for encryption and decryption, I suggest you use chars (8 bits = 256 values) for these when you read/write • Cipher Encryption works like this: • Take a numeric key and add that to each value in the alphabet • For example a key of 2 makes ac, bd, etc. • The word “hello” with key 2 becomes: “jgnnq” • What happens to “z”? • Wraps around back to a, then b (z b) • Use mod to get this effect on integers • Create the method: • public void cipherEncrypt( int key )
Exercises - FileUtility • Cipher Decryption works like this: • Take a numeric key and subtract value from each in the alphabet • For example a key of 2 makes ay, bz, etc. • The word “eqorwvgt” with key 2 becomes: “computer” • Create the method: • public void cipherDecrypt( int key ) • You can test your code by calling • cipherEncrypt( key ) • cipherDecrypt( key ) • The result is the file is restored if done correctly
Exercises - FileUtility • Password Encryption is a little different: • Take in a password and use it to fill the beginning of an array which contains the alphabet • Fill the array with values which have not been used yet • Suppose the password was “Secret” • The alphabet: {a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z} • becomes: {s,e,c,r,t,a,b,d,f,g,h,i,j,k,l,m,n,o,p,q,u,v,w,x,y,z} So the letter ‘a’ is now an ‘s’, The letter ‘b’ is now an ‘e’, … The word “testing” becomes “qtpqfkb” Create the methods public void passwordEncrypt( String word ) public void passwordDecrypt( String word ) *Your alphabet consists of all 256 chars, not just 26
Exercise – CSV files • CSV or comma separated values is a common/simple file type for displaying data in a table. • Columns are separated by commas and rows by new lines • Testing,1,2,3 Testing,A,B,C
Exercise – CSV files • Make a class that takes the path to a csv file in its constructor and loads the table of data into a 2D array (or ArrayList). • Add the following methods to the class: • public int rows() • Returns the number of rows in the CSV file • public int columns() • Returns the number of columns in the CSV file • public String getRow( String key ) • Searches the data and if key is found, returns the row of data where it was discovered
Exercise – CSV files • HTML tables have the following syntax: • <table> • <tr><td></td><td></td></tr> • … </table> Where tr marks the start of a row and td the start of a column • In the example: • Testing,1,2,3 • Testing,A,B,C • The html would be: <table> <tr><td>Testing</td><td>1</td><td>2</td><td>3</td></tr> <tr><td>Testing</td><td>A</td><td>B</td><td>C</td></tr> </table>
Exercise – CSV files • A google search can turn up more info on tables • The tags table, tr, and td also have options for line thickness/color, font, background color etc. • Create the method: • public void exportTo(String path, *options*) • Which creates a new .html file and exports the table there. The user must have at least 4 options included when they export • This could be the colors, font, lines etc.
Exercises - Greenfoot • Update your board game so that you can save and load it to/from a file. • When you resume a game it should continue from the same state as before • Score • Player’s turn • Pieces on Board • … • You may use any format that’s convenient • If you’d like to use the CSVFile class (or some of it’s code) you can also do that.