File Input/Output Tuesday, July 25 2006 CSE 1020, Summer 2006, Overview (1): Before We Begin Some administrative details Some questions to consider The Class Object What is the Object class? File Input and Output Overview Introduction File I/O Overview (2): Input/Output Streams Introduction Input Output As an Aside Code examples
Before We Begin Administrative Details (1): Some Reminders Lab Test 3 Tuesday, August 1 Last regularly scheduled lecture Thursday, August 3 will include exam review Final Exam Wednesday, August 16, 2006 7:00pm 10:00pm Vari Hall (VH) 3006 Some Questions to Consider (1): What is the Object class? Why have the Object class? What are some of the methods in the Object class? What happens if a method of the Object class is not overriden? What are the disadvantages of prompting the user for any required input? How does accessing input from a file overcome these disadvantages? How can we access the contents of a file?
File Input/Output Overview (1): About 100 Classes Dedicated to Input/Output (I/O) in the Java Library Located in the following packages java.io & java.nio Allow clients to delegate all I/O related operations We have actually already worked with I/O streams Scanner/PrintStream classes to read user input via the keyboard and to display to the screen We will now expand on our knowledge of this to cover I/O with files I/O with files allows for much more flexibility Introduction to File I/O (1): Programs Involving File I/O Typically start by prompting the user to enter the name of a file Can be done by simply the name of the file entered by the user as a String or You can use the standard file dialog box JFileChooser to allow the user to navigate through the file directory system and choose the desired file presents the user with a dialog window similar to what you see when you choose the Open menu option in a standard Windows application
Introduction to File I/O (2): Programs Involving File I/O (cont.) Open file dialog using JFileChooser JFileChooser filechooser = new JFileChooser(); filechooser.showopendialog(null); Part of the javax.swing package must have the following statement import javax.swing.* Introduction to File I/O (3): Programs Involving File I/O (cont.) Once the open file dialog window is displayed, the dialog will wait until the user takes an action Once the user performs an action (clicks on one of the button Open or Cancel, the program must examine the value of the reference obtained using the following method call chooser.getselectedfile(); If null user selected the Cancel option If not null invoke tostring to obtain file name Introduction to File I/O (4): Programs Involving File I/O (cont.) Example code segment related to getselectedfile if(chooser.getselectedfile()!= null) { String filename; filename = chooser.getselectedfile().tostring(); rest of program here } User doesn t have to explicitly choose a file by clicking on it in the file dialog can also enter the name of the file directly in the file name text field
File Input (1): Abstraction at Work Once the file name has been obtained, we can access its contents for reading in a simple manner making use of the familiar Scanner class Simply create an instance of the Scanner class passing the file name to its constructor as opposed to System.in Once the Scanner object is created then we use it as we normally do We do not have to be concerned with where the data is coming from Java hides that from us and allows for a common interface File Input (2): Abstraction at Work Creating the Scanner object to access a file for reading Of course, we can also create a Scanner object to handle keyboard input if we like both can be available to us at the same time Scanner fileinput = new Scanner(fileName); Scanner input = new Scanner(System.in); File Input (3): Reading From a File Similar to reading from the keyboard except for two differences No prompt is involved we do not have to prompt the user to enter anything since all the input already exists in the file Sentinels (character(s) indicating user is done are not required the file contains a hidden marker called end of file after its last field to indicate there is no more information contained in the file and we cannot read beyond it
File Input (4): Reading From a File (cont.) Scanner class contains a boolean method called hasnextx() that indicates whether the file contains more fields (of type X e.g., for int, use hasnextint) If all the fields in the file are of the same type (lets say int for example), then we can read its entire contents as follows while(fileinput.hasnextint()) { int x = fileinput.nextint(); } File Input (5): Reading From a File (cont.) Of course, we are not restricted to reading integers Can read any type including String when our file is a text-based document for example nextline You must be careful when mixing the reads between Strings and other primitive types Consider a file with the data 15\nText and the following calls will they work (e.g., will the int I be equal to 15 and the String s equal to Text?) int i = fileinput.nextint(); String s = fileinput.nextline(); File Output (1): Writing Data to a File Very similar to writing data to the display (screen) Instead of creating a PrintStream object through System.out, we do so through the constructor PrintStream fileoutput = new PrintStream(fileName); Can invoke any of the standard output methods we are familiar with print, println, printf Of course, as with file input, we can also create another instance of the PrintStream class to use for output to the screen
File Output (2): Writing Data to a File (cont.) An example of writing the numbers from 1-10 to a file, each on a separate line on its own Assume the file is called test.txt PrintStream fileoutput = new PrintStream( test.txt ); for(int index = 1; index <= 10; index++) { fileoutput.println(index); } File Output (3): Writing Data to a File (cont.) Some issues to consider when writing data to a file What if the file we specify does not exist? What if the file does exist and contains data in it will any existing data be lost? Will we simply append to it? Lets look at some examples to investigate these issue further I/O Streams
Introduction (1): What is a Stream? Think of it as a conduit Allows data to flow from the data origin point (e.g., keyboard, file etc.) to the point in our program where we access it With respect to the keyboard, Java contains an object of type java.io.inputstream Connected to the keyboard and ready to be used Keyboard plays the role of data source Program plays the role of data sink Input (1): Keyboard Input We can read from the keyboard as follow InputStream keyboard = System.out int input = keyboard.read(); API of read method indicates the method blocks until the user enters input User input is done when user presses ENTER Above method will return the character codes of the user input byte by byte each call to the read() method will return the next byte and will return -1 if called after last byte already read Input (2): Keyboard Input (cont.) But we haven t been reading from the keyboard using one byte at a time??? That would be very inconvenient would have to read each byte, convert to char and then somehow convert these chars to a int or float We delegate the work Reader conversion of byte stream to char stream Buffer collects chars until full line is accumulated and delivered to us when we asked
Input (3): Keyboard Input (cont.) Graphical illustration of the reader and buffer Input (4): Keyboard Input (cont.) Can employ delegation even further Rather than our application handling exchange of data between the reader and the buffer, why not have the reader report directly to the buffer? all we have to do then is deal with the buffer! Input (5): Keyboard Input (cont.) We can then create the needed instances bottomup and pass them to the constructor of the next aggregate in the chain InputStream keyboard = System.in; InputStreamReader reader = new InputStreamReader(keyboard); BufferedReader buffer = new Buffer(reader); We can now read input easily one line at a time by accessing the buffer only String input = buffer.readline()
Input (6): File Input (cont.) Very similar to keyboard input Still need to convert bytes to characters and to buffer the data except we now need an additional stream that connects to the file the FileInputStream does this for us Output (1): Screen Output We can write to the screen by establishing a data connection that begins in our application and ends at the screen This is an output stream since data moves away from our program As we know, Java comes with object of type java.io.printstream that is already connected to the screen leaves a reference of this as a field (called out) in the System class Output (2): File Output To write data to a file, we must delegate the aggregation shown below PrintWriter Accepts data of any primitive type or String and converts it to a character stream BufferedWriter Write text to a characteroutput stream, buffering characters
Output (3): File Output (cont.) OutputStreamWriter a bridge from character streams to byte streams FileOutputStream takes bytes from a stream and writes them to a file Such an approach does work but is inefficient Overhead incurred by the writer is expanded per character better to ask the writer to convert a whole string of characters at a time rather than one character at a time Output (4): File Output (cont.) Overhead incurred by the writer is expanded per character better to ask the writer to convert a whole string of characters at a time rather than one character at a time Buffer before the Writer As an Aside (1): Closing Streams All streams are auto-closed when a program ends without a run-time error Can also explicitly close a stream using the close() method good idea to do so! Closing an output stream will not only free resources but it will also flush the buffer Write any data that may still be in the buffer to the file Can also invoke the flush() method explicitly
As an Aside (2): Examples of File I/O Lets write and examine some code examples related to file I/O