380 likes | 391 Views
Learn to store data in Java using text and binary formats. Understand ASCII encoding in text files and UNICODE storage for characters. Explore Text I/O with Java's Reader and Writer classes. Discover how to read data character by character or line by line from text files.
E N D
Two Ways to Store Data in a File • Text format • Binary format
Text Format Information stored as a sequence of characters Characters are stored as their ASCII equivalent - int value 12345 stored as ‘1’ ‘2’ ‘3’ ‘4’ ‘5’ 5 bytes 91 92 93 94 95 A text file is ‘readable’ by humans. Java classes ‘Reader’ and ‘Writer’ (and their subclasses) are for use with text files.
Text I/O • In Java, characters are stored using UNICODE. • Reader objects read characters in the current O.S. format, and convert them to UNICODE storage format. • Writer objects convert the UNICODE stored data to character encoding used by the current O.S. • Reader and Writer are abstract classes
Text Input READER class is an abstract class which is: extended by InputStreamReader which is extended by FileReader extended by BufferedReader Reader class provides abstract methods which will be implemented specifically by all subclasses InputStreamReader object reads bytes from an input stream and decodes them into characters, using the platform’s charset (ASCII for Windows). These characters are converted to UNICODE for storage. read() reads one character (number of bytes depends on charset) FileReader object inherits InputStreamReader capabilities, but the stream is a file. BufferedReader object is a wrapper for any InputStreamReader (including FileReader), and provides buffering (ie. handles multiple char reads and provides a string)
Text one char at a time • Create a InputStreamReader object Constructor takes an input stream, which may be keyboard, network connection, any input source InputStreamReader in = new InputStreamReader(System.in); • InputStreamReader extends the Reader class, implementing input methods specifically for files • Use its read method to read a single character • returns the next char as an int • or the integer -1 at end of input • Test for -1 to determine if a char was read
Reading one char at a time…. InputStreamReader reader = new InputStreamReader(System.in); char c; //Java chars are UNICODE int next = reader.read() ; //byte read and if (next != -1) c = (char)next(); // process c next = reader.read() ; } //See demo testISReader.java
Reading one line at a time…. InputStreamReader in = new InputStreamReader(System.in);//input is from keyboard BufferedReader bin = new BufferedReader(in); String val; val = bin.readLine(); // get one string from keyboard while(val != null) { //while user does not enter CTRL Z System.out.println( val ); System.out.flush(); //output any lines waiting to be printed val = bin.readLine(); } //See demo testBISReader.java
Text one char at a time from a file • Create a FileReader object • FileReader extends the Reader class, implementing input methods specifically for files • Use its read method to read a single character • returns the next char as an int • or the integer -1 at end of input • Test for -1 to determine if a char was read • Close the file when done
Reading one char at a time from file…. FileReader reader = new FileReader("input.txt"); char c; //Java chars are UNICODE int next = reader.read() ; //byte read and if (next != -1){ c = (char)next(); next = reader.read(); reader.close(); // see testFileReader.java
Reading Text Line by Line Create a BufferedReader object (pass a FileReader object to constructor) objects of type BufferedReader can group characters – ‘buffer’ them method readLine() available, to provide file data 1 line at a time (the method handles reading the characters from the FileReader for you) readLine() returns the next line of file (as a String), or null if none exists
//Reads first line from file named input.txt // line is expected to contain a double value FileReader reader = new FileReader("input.txt"); BufferedReader in = new BufferedReader(reader); String inputLine = in.readLine(); double x = Double.parseDouble(inputLine);
//Reads and all lines from file // and writes them to console import java.io; public class demo{ public static void main(String[] args)throw IOException{ FileReader reader = new FileReader("input.txt"); BufferedReader in = new BufferedReader(reader); String line = in.readLine(); While (line != null){ System.out.println(line); line = in.readLine(); } in.close(); } }
Text Output WRITER class is an abstract class which is: extended by OutputStreamWriter which is extended by FileWriter extended by PrintWriter Writer class provides abstract methods which will be implemented specifically by all subclasses OutputStreamWriter object writes bytes to an output stream and encodes them into characters, using the platform’s charset (ASCII for Windows). These characters are converted from stored UNICODE write(char) writes one character (number of bytes written depends on charset) Object is buffered, may be flushed FileWriter object is inherits OutputStreamWriter capabilities, but the stream is a file PrintWriter object is a wrapper for any OutputStreamWriter, and provides buffering (ie. handles multiple char writes and provides a string)
Write a Character to File FileWriter class implements Writer methods specifically for files. FileWriter writer = new FileWriter("output.txt"); char c =‘a'; writer.write(c); writer.close();
Writing Strings to Text Files A PrintWriter object handles the ‘unbuffering’ of data for output file writer Create PrintWriter object (pass FileWriter object to constructor) PrintWriter class provides ‘println’ method which accepts String and uses FileWriter to print one char at a time. FileWriter writer = new FileWriter(“output.txt”) PrintWriter out = new PrintWriter(writer);
//use PrintWriter object to output data to file output.txt FileWriter writer = new FileWriter(“output.txt”) PrintWriter out = new PrintWriter(writer); out.println(29.95); out.println(new Rectangle(5,10,15,25)); out.println("Hello, World!");
StringTokenizer Class When reading a line of text, we get a single long string. Suppose our line of text looked something like: John|Doe|16|1998 In other words, the string contained know ‘delimiters’, and we wanted to access the ‘pieces’ between these delimiters. Java.util package provides a class to help here: StringTokenizer Methods: StringTokenizer(String theline, String delimiters) boolean hasMoreTokens() String nextToken() int countTokens() see file CountTHE.java
Binary Format More compact and efficient int 12345 stored using binary representation: 00000000 00000000 0010000 0011100 00 00 48 57 4 bytes Java abstract classes InputStream and OutputStream (and their subclasses)provide methods for reading and writing these types of files
Binary File I/O • In Java, an object from which we can read a sequence of bytes is called an input stream. • An object to which we can write a sequence of bytes is called an output stream. • I/O streams have beginning, end, and are read sequentially. • InputStream and OutputStream are abstract classes.
InputStream class has an abstract method abstract int read() // reads and returns one byte An abstract method is an method which MUST be implemented by any extending class. The idea is that the extending class provides specifics… OutputStream class has an abstract method abstract void write(int b); // writes one byte to output Java provides many stream classes which extend from InputStream and OutputStream that let you work with data in the forms that you normally use……….
Byte Streams InputStream is extended by FileInputStream which is used for byte based input from a file OutputStream is extended by FileOutputStream which is used for byte based output to a file Both of these classes implement read and write methods as specified in their abstract super classes. see file ByteIO.java
Input Byte Streams InputStream is extended by FilterInputStream FilterInputStream is extended by DataInputStream FilterInputStream acts as a ‘wrapper’ for an InputStream objects, which it uses as its basic source of data. Methods of FilterInputStream objects simply pass requests to the InputStream objetct. Each subclass of FilterInputStream transforms the data along the way, or provides some additional functionality. For example, DataInputStream ‘wraps’ a InputStream object and assembles bytes read into numerical types. ** readInt, readDouble, readBoolean are just some of the methods available with a DataInputStream object See file DataByteIO.java
Input Byte Streams InputStream is extended by FilterInputStream FilterInputStream is extended by BufferedInputStream Another subclass of FilterInputStream is BufferedInputStream. BufferedInputStream ‘wraps’ a InputStream object and provides ‘buffering’ for efficiency. BufferedInputStream overloads ‘read’ so that in addition to one byte at a time, one byte array can be read. // buffered input BufferedInputStream bin = new BufferedInputStream(new InputStream(“file.txt”)); // add another layer so that DataInputStream object will not do individual reads // for each byte, but use the buffered reads DataInputStream dbin = new DataInputStream(bin);
Output Byte Streams FilterOutputStream extends OutputStream (Subclasses may be superclasses themselves) PrintStream extends FilterOutputStream FilterOutputStream acts as a ‘wrapper’ for an OutputStream object, which it uses as its basic depository of data. Methods of FilterOutputStream simply pass requests to the OutputStream objetct. PrintStream ‘wraps’ a OutputStream and provides an accurate display of data types to the output, in addition to buffering. PrintStream also provides the overloaded println, which accepts String and byte[] parameters, as well as byte. System.out, is an object of type PrintStream, which is provided by the System class in the java.lang input. System.out ‘wraps’ the OutputStream object representins the console.
FILE OBJECTS provide methods which allow the creation, deletion, and other file manipulation/status methods… FileInputStream and FileReader constructors are overloaded to accept a File object. The file object will allow you to check the status of a file before you open it!! File f = new File(“in.txt”); if ( ! f.exists() ) System.out.println(“file does not exist”); else if ( ! F.canRead() ) System.out.println(“file cannot be read”); else { FileInputStream in = new FileInputStream(f); BufferedInputStream bufIn = new BufferedInputStream(in); int bb = bufIn.read();
File Dialogs • Use JFileChooser to let a user supply a file name through a file dialog • Construct a file chooser object • Call its showOpenDialog or showSaveDialog method (Specify null or the user interface component over which to pop up the dialog ) • If the user chooses a file:JFileChooser.APPROVE_OPTION is returned • If the user cancels the selection:JFileChooser.CANCEL_OPTION is returned • If a file is chosen, use GetSelectedFile method to obtain a File object describing the file
Code to Use a JFileChooser JFileChooser chooser new JFileChooser(); FileReader in; if (chooser.showOpenDialog(null) == JFileChooser.APPROVE_OPTION) { File selectedFile = chooser.getSelectedFile(); in = new FileReader(selectedFile); } else in = null; // see file testDialog.java
Mark and Reset The abstract classes InputStream and Reader provide: void mark (int byteLimit) * Marks the current position in this input stream. A subsequent call to the reset method repositions this stream at the last marked position so that subsequent reads re-read the same bytes. * byteLimit is the number of bytes that can be read before this mark becomes invalid void reset() * repositions stream to position when mark was last called boolean markSupported () indicates if a stream supports these methods
int[] intList; intList = new int[100]; //this file contains one number 66 FileReader file = new FileReader("number.txt"); BufferedReader ifile = new BufferedReader(file); // all array elements are initialized to 66 ifile.mark(5); for (int i = 0; i<100; i++){ String sVal = ifile.readLine(); ifile.reset(); intList[i] = Integer.parseInt(sVal); }
Object Output Another byte (binary) I/O class which extends from OutputStream is ObjectOutputStream ObjectOutputStream class can save entire objects to disk ! Objects that are written to an object stream must belong to a class that implements the Serializable interface. class Coin implements Serializable { ... } ** Serializable interface has no methods.
Serializable • Objects that are written to an object stream must belong to a class that implements the Serializable interface. class Coin implements Serializable { ... } ** Serializable interface has no methods.
ObjectOutputStream methods Stream does not just write objects …….. write( ) - writes a byte writeInt(int) - writes a 32 bit int writeDouble(double) - writes a 64 bit double writeChar(char) - writes a 16 bit char writeObject(Object) - writes the specified object to the output stream (if Serializable) close() - closes stream
Writing an Object to a File OutputStream os = new FileOutputStream("data.txt"); ObjectOutputStream out = new ObjectOutputStream(os); ArrayList<Box> boxlist = new ArrayList<Box> (); boxlist.add(new Box(5)); boxlist.add(new Box(17)); boxlist.add(new Box(20)); out.writeObject(boxlist); out.close();
Object Input • Another byte (binary) I/O class which extends from InputStream is ObjectInputStream ObjectInputStream class can read from a file, written by ObjectOutputStream (Data must by read with respect to datatype and order with which it was written)
ObjectInputStream methods read( ) - reads a byte readInt() - reads a 32 bit int readDouble() - reads a 64 bit double readChar() - reads a 16 bit char readObject( ) - reads the specified object to the input stream (if Serializable) close() - closes stream
Reading from File containing Objects public static void main(String[] args) throws IOException,ClassNotFoundException { InputStream is = new FileInputStream("data.txt"); ObjectInputStream in = new ObjectInputStream(is); ArrayList<Box> boxlist = (ArrayList<Box>) in.readObject(); for (int i = 0; i< boxlist.size(); i++) System.out.println(boxlist.get(i)); in.close();
Random .vs. Sequential Access • Sequential access • A file is processed a byte at a time. • Random access • Allows access at arbitrary locations in the file