310 likes | 347 Views
Learn about file handling in Java using FileReader, FileWriter, FileInputStream, FileOutputStream. Understand try-catch blocks and file reading techniques.
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.