450 likes | 569 Views
Java Programming. Input / Output Chapter 13. Input/Output Files. We use files all the time Programs are files Documents are files We want them to be “permanent” To last beyond execution of a program We want to access and use them again A file can be input into or output from a program.
E N D
Java Programming Input / Output Chapter 13
Input/Output Files • We use files all the time • Programs are files • Documents are files • We want them to be “permanent” • To last beyond execution of a program • We want to access and use them again • A file can be input into or output from a program
Input/Output Files • Open file • Create object • Associate stream of bytes with it • Close file • Make it no longer available to application • Should always close every file you open • Stream • Bytes flowing into program from input device • Bytes flow out of application to output device • Most streams flow in only one direction
Streams • A stream is an object that enables the flow of data between a program and some I/O device or file • If the data flows into a program, then the stream is called an input stream • If the data flows out of a program, then the stream is called an output stream
Streams • Input streams can flow from the keyboard or from a file • System.in is an input stream that connects to the keyboard Scanner keyboard = new Scanner(System.in); • Output streams can flow to a screen or to a file • System.outis an output stream that connects to the screen System.out.println("Output stream");
Text Files • Files that are designed to be read by human beings, and that can be read or written with an editor are called text files • Text files can also be called ASCII files because the data they contain uses an ASCII encoding scheme • An advantage of text files is that the are usually the same on all computers, so that they can move from one computer to another
Binary Files • Files that are designed to be read by programs and that consist of a sequence of binary digits are called binary files • Binary files are designed to be read on the same type of computer and with the same programming language as the computer that created the file • An advantage of binary files is that they are more efficient to process than text files
Using the File Class • File class • Gather file information • java.io package • Open a file File someData = new File("Data.txt"); File someData = new File("C:\\MyDocuments\\Data.txt");
Using the File Class import java.io.*; public class FileOpen { public static void main(String[ ] args) { File myFile = new File("Data.txt" ); if(myFile.exists( )) { System.out.println(myFile.getName( ) + " exists"); System.out.println(" The file is " + myFile.length( ) + " bytes long"); if (myFile.canRead( )) System.out.println("OK to read"); else System.out.println("not OK to read"); } else System.out.println("File does not exist"); } }
Using Scanner • The class Scanner can be used for reading from the keyboard as well as reading from a text file • Simply replace the argument System.in (to the Scanner constructor) with a suitable stream that is connected to the text file Scanner SomeData = new Scanner(new File("Data.txt")); • Methods of the Scanner class for reading input behave the same whether reading from the keyboard or reading from a text file • For example, the nextIntand nextLine methods
Using Scanner • Write code to read data from a file: • Imagine you are reading data from keyboard • Put usual Scanner and next codes in program • Add some extra items • Add import declaration: import java.io.* • Use java.io.File and java.io.IOException • Type throws IOExceptioninto method header • Type new File(“ “) into your call to new Scanner • Type file name inside quotation marks • Use next, nextLine, nextInt, etc
Using the Scanner import java.util.Scanner; import java.io.* public class FileOpen { public static void main(String[ ] args) throws IOException{ Scanner input = new Scanner(new File("Data.txt" )); String line1 = input.nextLine( ); String line2 = input.nextLine( ); System.out.println(line1); System.out.println(line2); } }
Writing to a Text File • How do we save data to a text file? • We can produce an object of the class PrintWriter that is connected to the file FileName • The process of connecting a stream to a file is called opening the file • If the file already exists, then doing this causes the old contents to be lost • If the file does not exist, then a new, empty file named FileName is created • After doing this, the methods print and println can be used to write to the file
Writing to a Text File • PrintWriter • Create an object using PrintWriter PrintWriter output = new PrintWriter("Data.txt")); • We can now print to the text file using print or println • Instead of System.out, we will use our new object output.println("This goes to our new file“);
Writing to a Text File • When a program is finished writing to a file, it should always close the stream connected to that file outputStreamName.close(); • This allows the system to release any resources used to connect the stream to the file • If the program does not close the file before the program ends, Java will close it automatically, but it is safest to close it explicitly
Writing to a Text File • Output streams connected to files are usually buffered • Rather than physically writing to the file as soon as possible, the data is saved in a temporary location (buffer) • When enough data accumulates, or when the method flush is invoked, the buffered data is written to the file all at once • This is more efficient, since physical writes to a file can be slow
Writing to a Text File • The method close invokes the method flush, thus insuring that all the data is written to the file • If a program relies on Java to close the file, and the program terminates abnormally, then any output that was buffered may not get written to the file • Also, if a program writes to a file and later reopens it to read from the same file, it will have to be closed first anyway • The sooner a file is closed after writing to it, the less likely it is that there will be a problem
File Output import java.io.* public class FileOutput { public static void main(String[ ] args) throws IOException{ PrintWriterlistOut = new PrintWriter("List.txt"); listOut.println("This is our printout"); listOut.close( ); } }
Binary Files • Data stored in a text file are represented in human-readable form. • Data stored in a binary file are represented in binary form. • You cannot read binary files. • Binary files are designed to be read by programs. • The advantage of binary files is that they are more efficient to process than text files. • We can use Streams to handle binary files
Using Streams • InputStream and OutputStream • Abstract classes that contain methods for performing input and output
Buffered Input Streams • One of the ways to improve the performance of a program that reads input streams is to buffer the input • Buffering is the process of saving data in memory for use later when a program needs it • When a Java program needs data from a buffered input stream, it looks in the buffer first, which is faster than reading from a source such as a file
BufferedReader • The class BufferedReader is a stream class that can be used to read from a text file • An object of the class BufferedReader has the methods read and readLine • A program using BufferedReader, like one using PrintWriter, will start with a set of import statements: import java.io.BufferedReader; import java.io.FileReader; import java.io.FileNotFoundException; import java.io.IOException;
BufferedReader • This stream class uses FileReader to convert the file name to an object that can be used as an argument • A stream of the class BufferedReader is created and connected to a text file as follows: BufferedReadersomeData= new BufferedReader(new FileReader("Data.txt")); • This opens the file for reading
BufferedReader • After these statements, the methods readand readLine can be used to read from the file • The readLine method is the same method used to read from the keyboard, but in this case it would read from a file • The read method reads a single character, and returns a value (of type int) that corresponds to the character read • Since the read method does not return the character itself, a type cast must be used: char next = (char)(someData.read());
BufferedReader • Unlike the Scanner class, the class BufferedReader has no methods to read a number from a text file • Instead, a number must be read in as a string, and then converted to a value of the appropriate numeric type using one of the wrapper classes • To read in a single number on a line by itself, first use the method readLine, and then use Integer.parseInt, Double.parseDouble, etc. to convert the string into a number • If there are multiple numbers on a line, StringTokenizer can be used to decompose the string into tokens, and then the tokens can be converted as described above
BufferedReader import java.io.* public class FileOpen { public static void main(String[ ] args) throws IOException{ BufferedReader input = new BufferedReader(new FileReader("Data.txt" )); String line1 = input.readLine( ); String line2 = input.readLine( ); input.close( ); System.out.println(line1); System.out.println(line2); } }
Using Streams • Objects can also be input and output from a binary file • Use the writeObject method of the class ObjectOutputStream to write an object to a binary file • Use the readObjectmethod of the class ObjectInputStream to read an object from a binary file
Using Streams • The class ObjectInputStream is a stream class that can be used to read from a binary file • An object of this class has methods to read strings, values of primitive types, and objects from a binary file • A program using ObjectInputStream needs to import several classes from package java.io: import java.io.ObjectInputStream; import java.io.FileInputStream; import java.io.IOException;
Using Streams • An ObjectInputStream object is created and connected to a binary file as follows: ObjectInputStreamsomeData = new ObjectInputStream( new FileInputStream(("Data.txt")); • The constructor for FileInputStream may throw a FileNotFoundException • The constructor for ObjectInputStream may throw an IOException • Each of these must be handled
Using Streams • After opening the file, ObjectInputStreammethods can be used to read to the file • Methods used to input primitive values include readInt, readDouble, readChar, and readBoolean • The method readUTF is used to input values of type String • If the file contains multiple types, each item type must be read in exactly the same order it was written to the file • The stream should be closed after reading
Using Streams • Reading and writing strings and characters may need to be converted to binary components. The computer can handle Unicode which consists of two bytes: • UTF-8 is a coding scheme that allows systems to operate with both ASCII and Unicode efficiently. • Most operating systems use ASCII. • Java uses Unicode. • The ASCII character set is a subset of the Unicode character set.
Using Streams • To construct a ObjectOutputStream, use the following constructors: FileOutputStream ("Data.txt") FileOutputStream("Data.txt", boolean append) • If the file does not exist, a new file would be created. If the file already exists, the first constructor would delete the current contents in the file. • To retain the current content and append new data into the file, use the last constructor by passing true to the append parameter.
Serializable • Not all objects can be written to an output stream. Objects that can be written to an object stream is said to be Serializable • The Serializable interface is easy to use and requires no knowledge of interfaces • A class that implements the Serializableinterface is said to be a serializable class
Serializable • In order to make a class serializable, simply add implements Serializable to the heading of the class definition public class SomeClass implements Serializable • When a serializable class has instance variables of a class type, then all those classes must be serializable also • A class is not serializable unless the classes for all instance variables are also serializable for all levels of instance variables within classes
Random Access to Binary Files • The streams for sequential access to files are the ones most commonly used for file access in Java • However, some applications require very rapid access to records in very large databases • These applications need to have random access to particular parts of a file
Random Access Files • The stream class RandomAccessFile, which is in the java.io package, provides both read and write random access to a file in Java • A random access file consists of a sequence of numbered bytes • There is a kind of marker called the file pointer that is always positioned at one of the bytes • All reads and writes take place starting at the file pointer location • The file pointer can be moved to a new location with the method seek
Random Access Files • Although a random access file is byte oriented, there are methods that allow for reading or writing values of the primitive types as well as string values to/from a random access file • These include readInt, readDouble, and readUTF for input, and writeInt, writeDouble, and writeUTF for output
Random Access Files • The constructor for RandomAccessFiletakes either a string file name or an object of the class File as its first argument • The second argument must be one of four strings: • "rw", meaning the code can both read and write to the file after it is open • "r", meaning the code can read from the file, but not write to it RandomAccesssomeData = new RandomAccess( "Data.txt", "rw"));
Do You Have a Room? • You are sitting behind the desk at the Java Hotel. Here comes a party of 4 and they would like a room. You need to check to see if a room is vacant. If one is, you then need to modify the guest list when you assign the room
Do You Have a Room? • First let’s create the Guest list file import java.io.*; class GuestList { public static void main(String[ ] args) throws IOException{ int guests [] = {1, 4, 2, 0, 0, 2, 4, 1, 0, 1}; introomNum; PrintStreamlistOut = new PrintStream("GuestList.txt"); for (roomNum = 0; roomNum < 10; roomNum++){ listOut.print(guests[roomNum]); listOut.print(" "); } listOut.close( ); } }
Do You Have a Room? • Now we need to create the code to check for an available room • We need to open and read the file • We need to verify if a room is unoccupied • We need to ask the how many in your party • We need to update the GuestList file
Do You Have a Room? import java.util.Scanner; import java.io.*; class FindVacancy { public static void main(String[ ] args) throws IOException{ int guests [ ] = new int[10]; introomNum; Scanner input = new Scanner(System.in); Scanner file = new Scanner(new File("GuestList.txt")); for (roomNum = 0; roomNum < 10; roomNum++) guests[roomNum] = file.nextInt(); // continued on next slide
Do You Have a Room? roomNum = 0; while (roomNum < 10 && guests[roomNum] != 0) roomNum++; if (roomNum == 10) System.out.println("Sorry, no vacancy"); else { System.out.println("How many people for room " + roomNum + " ?"); guests[roomNum] = input.nextInt( ); PrintStreamlistOut = new PrintStream("GuestList.txt"); for (roomNum = 0; roomNum < 10; roomNum++){ listOut.print(guests[roomNum]); listOut.print(" "); } } } }