Survey
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
CPAN322 Java Application Programming Lecture #2: Streams and Files Data stored into variables are lost as soon as the program is terminated. Persistent data are data maintained in files either in a text format or in a binary format. A stream is composed of bytes or characters that you can read from or write to. Java looks at a file as a stream of bytes. When a file is opened , an object is created and a stream is associated with the object. Three standard streams are created automatically when a Java program is executed; System.in, System.out, System.err Java uses streams to handle input and/or output and provides the package java.io for this reason. This package provides classes for writing and reading to character oriented, binary oriented streams. It also provides classes for working with random access files ,working with object serialization and more. Character oriented streams: The classes Reader and Writer are the base classes for working with character oriented input/output. These classes are not used directly, but through derived classes from them. The class File is not a stream class , but is used to find information about a file such as it’s size, permission, date, and so on. InputStreamReader and OutputStreamReader are designed for character input and output. FileReader and FileWriter classes are used to read character data from a file and write characters data to a file. CharArrayInputStream and CharArrayOutputStream are used to read character data from an array and write characters data to an array respectively. BuffredReader and BuffredWriter classes provides a buffered character reader and writer. The class PrintWriter also is used to write text to a file by breaking up numbers and strings to individual characters and then write them to the file. Byte oriented streams: The classes InputStream and OutputStream are the base classes for working with bytes oriented input/output. These classes are not used directly, but through derived classes from them. The classes FileInputStream and FileOutputStream are designed to work with byte oriented input and byte oriented output from files. 1 ByteArrayInputStream and ByteArrayOutputStream are designed to work with input stream from an array of bytes and output stream to an array of bytes respectively. Classes BufferedIuputSteam enable you to reset the stream and go pack to an earlier position. Working with Object Streams (Serialization) Serialization is the process of writing objects to a stream and reading them back. These objects must implements Serializable interface. To serialize an object we have to use ObjectOutputStream and ObjectInputStream. To write objects to and read them from a file. ObjectOutputStream must be used in conjunction with FileOutputStream and ObjectInputStream with FileInputStream. Working with random access files: Random access files enable direct access to individual records stored in them without searching through other records. RandomAccessFile class support both writing to and reading from random access files. Data can be inserted to a random access file without destroying other data. Also existing data can be updated or deleted. The seek method of this class enables us to move around a random file by calculating the location of a certain record. We can open a random file for read, write or both. To make the process of locating certain record easier, all the records are required to have the same fixed-length. To write to and read from a random access file, we have first to create one: RandomAccessFile m_file1 = new RandomAccessFile("out.dat", "rw"); Rarely single fields are written to a file. Usually instance(s) of an object are written to a random file and the specific object must implements Serializable interface. The object should also provide methods for reading and writing records to the random file. For example: SimpleUser su1 = new SimpleUser(123,"john", true,3000); su1.writeUser(m_file); Where writeUser method is defined in Ex13; Records in a random access file can be access sequentially as shown below: RandomAccessFile m_file1 = new RandomAccessFile("out.dat", "r"); SimpleUser su = new SimpleUser(); 2 do { su.read(m_file1); System.out.println(su.toString()); } while (su.getUserNumber()==0); Where read method is defined in Ex13; As an alternative, records can be accessed randomly using seek method: m_file1.seek(1 * su.getSize()); Examples: Ex1: fileEx.java This example obtains some information about a file: import java.io.*; class fileEx { public fileEx() { File fi = new File("fileEx.java"); System.out.println("File name is: " + fi.getName()); System.out.println(" The size of this file is : " + fi.length()); System.out.println("The path of this file is " + fi.getPath()); System.out.println(fi.exists() ? "File exists" : "File does not exist"); System.out.println(fi.canRead() ? "File can be read from" :"File cannot be read from"); System.out.println(fi.canWrite() ? "File can be written to" :"File cannot be written to"); System.out.println(fi.isDirectory() ? "File is a directory" :"File is not a directory"); System.out.println("The file last modification date is : " + fi.lastModified()); } public static void main(String args[]) { new fileEx(); } } 3 Ex2: InputStreamReaderEx.java This example shows how to read character input from the keyboard: import java.io.*; class InputStreamReaderEx { public InputStreamReaderEx() { try { int ch; InputStreamReader isr = new InputStreamReader(System.in); System.out.println("Please enter a text then hit enter key"); while ((ch= isr.read()) != -1) { System.out.print((char) ch); } } catch(IOException e) { System.out.println("IOException :"+e.toString()); } } public static void main(String args[]) { new InputStreamReaderEx(); } } Ex 3:fileWriterReaderEx.java This example uses FileWriter to write character data to a file and FileReader to read character data from this file: import java.io.*; class fileWriterReaderEx { public fileWriterReaderEx() { try { 4 // construct a FileWriter object to write character data to the file fwr.txt File f=new File("fwr.txt"); FileWriter fw=new FileWriter(f); fw.write ("Hello world"); fw.close(); int size=(int)f.length(); // construct a FileReader object to read character data from the file fwr.txt FileReader fr=new FileReader(f); char character[]=new char[size]; fr.read(character); System.out.println(character); } catch(IOException e) { System.out.println("IOException :"+e.toString()); } } public static void main(String args[]) { new fileWriterReaderEx(); } } Ex4:chararrayWriterReaderEx.java In this example we will write character data to an array and read them back: import java.io.*; public class chararrayWriterReaderEx { public chararrayWriterReaderEx() { char data[]; // construct a CharArrayWriter object to write character data to an array CharArrayWriter chw=new CharArrayWriter(); int ch; try { // write character data to the CharArrayWriter object 5 chw.write("Hello World"); chw.flush(); chw.close(); // store the input from buffer of the CharArrayWriter to the array data data=chw.toCharArray(); // construct a CharArrayReader object to read character data from //the array data character by character CharArrayReader chr= new CharArrayReader(data); while((ch = chr.read()) != -1) { System.out.println((char)ch); } } catch(IOException e) { System.out.println("IOException :"+e.toString()); } } public static void main(String args[]) { new chararrayWriterReaderEx(); } } Ex 5: bufferedCharKeyboardEx.java In this example we will read character data from the keyboard and write them to the file bck.txt: import java.io.*; class bufferedCharKeyboardEx { public bufferedCharKeyboardEx() { try { // construct a buffered input stream reader to read input from the keyboard InputStreamReader in = new InputStreamReader(System.in); 6 BufferedReader br = new BufferedReader(in); String input; // cosntruct a buffered file writer to write the text to a file FileWriter fw=new FileWriter(new File("fbck.txt")); BufferedWriter bw=new BufferedWriter(fw); bw.flush(); // read character data from the keyboard while((input = br.readLine()) != null) { // write character data to the file fbck.txt bw.write(input); bw.newLine(); bw.flush(); } br.close(); bw.close(); } catch(IOException e) { System.out.println("IOException :"+e.toString()); } } public static void main(String args[]) { new bufferedCharKeyboardEx(); } } Ex6: bufferedWriterReaderEx.java This example uses bufferedWriter in conjunction with FileWriter to write character data to the file fbwr.txt and bufferedReader in conjunction with FileReader to read the character data back from the file fbwr.txt import java.io.*; class bufferedWriterReaderEx { public bufferedWriterReaderEx() { try 7 { //write some text to the file fbwr.txt FileWriter fw=new FileWriter(new File("fbwr.txt")); BufferedWriter bw=new BufferedWriter(fw); bw.flush(); bw.write("This is the first line in the file"); bw.newLine(); bw.write("This is the second line "); bw.close(); // read the text back from fbwr.txt FileReader fr = new FileReader("fbwr.txt"); BufferedReader br = new BufferedReader(fr); String input; while((input= br.readLine()) != null) { System.out.println(input); } fr.close(); } catch(IOException e) { System.out.println("IOException :"+e.toString()); } } public static void main(String args[]) { new bufferedWriterReaderEx(); } } Ex7:streamTokenizer.java In this example we will write some character data to a file, then read the character data from the file word by word: import java.io.*; class streamTokenizerEx { public streamTokenizerEx() { try { // writing some character data to the file fst.txt FileWriter fw=new FileWriter(new File("fst.txt")); 8 BufferedWriter bw=new BufferedWriter(fw); bw.flush(); bw.write("This is the first line in the file"); bw.newLine(); bw.write("This is the second line "); bw.close(); // use StreamTokenizer to read words tokens from fst.txt FileReader fr = new FileReader("file.txt"); StreamTokenizer st= new StreamTokenizer(fr); // read till the end of the file while(st.nextToken() != StreamTokenizer.TT_EOF) { // tokenize word if(st.ttype == StreamTokenizer.TT_WORD) System.out.println(st.sval); } fr.close(); } catch(IOException e) { System.out.println("IOException :"+e.toString()); } } public static void main(String args[]) { new streamTokenizerEx(); } } Ex8:fileOutputInputStreaemEx.java This example uses FileOutputStream to write byte data to a file and FileInputStream to read them back. The method skip of FileInputStream will be used to skip some bytes while reading the byte data from the file. import java.io.*; class fileOutputInputStreamEx { public fileOutputInputStreamEx() { int size; byte data1[] = "This is the first line".getBytes(); byte data2[]="This is the second line".getBytes(); try 9 { /* writing bytes to the file ffo.txt */ FileOutputStream fos= new FileOutputStream("ffo.txt"); for (int loop_index = 0; loop_index < data1.length; loop_index++) { fos.write(data1[loop_index]); } fos.write(data2); fos.close(); /* read bytes from the file ffo.txt */ FileInputStream fis = new FileInputStream("ffo.txt"); size = fis.available(); System.out.println("Total bytes in the file are: " + size); System.out.println("The first 5 bytes in the file are"); byte ba[] = new byte[5]; byte bo[]=new byte[size-10]; if (fis.read(ba) != 5) { System.out.println("bytes were not found"); } System.out.println(new String(ba, 0, 5)); // skip 5 bytes fis.skip(5); System.out.println("The rest of the bytes after skipping 5 more are:"); if (fis.read(bo) != (size-10)) { System.out.println("bytes were not found"); } System.out.println(new String(bo, 0, (size-10))); fis.close(); } catch(IOException e) { System.out.println("IOException"+e.toString()); } } 10 public static void main(String args[]) { new fileOutputInputStreamEx(); } } Ex9: byteArrayOutputInputStreamEx.java In this example we will write byte data to an array of bytes and store them to a file. After that we will read the byte data back from the array of bytes. import java.io.*; class byteArrayOutputInputStreamEx { public byteArrayOutputInputStreamEx() { // construct a ByteArrayStream object ByteArrayOutputStream baos= new ByteArrayOutputStream(); byte data[] = "This is a string".getBytes(); try { // write data from the byte array to the ByteArrayStream object baos.write(data); // write the data from the ByteArrayStream to the file baos.txt FileOutputStream fos = new FileOutputStream("baos.txt"); baos.writeTo(fos); fos.close(); //construct a ByteArrayInputStream object from an array of bytes ByteArrayInputStream in = new ByteArrayInputStream(data); int ch; // read byte data from the array of bytes while((ch = in.read()) != -1) { System.out.print((char) ch); } } catch(IOException e) { System.out.println("IOException "+ e.toString()); } 11 } public static void main(String args[]) { new byteArrayOutputInputStreamEx(); } } Ex10: This example uses the methods mark and reset of class BufferedInputStream to reset a stream of bytes and go back to a specific location in the stream. The application will write byte data to a ByteArrayOutputStream object from an array of bytes. To read data from the array of bytes, we need to construct a ByteArrayInputStream. To use mark and reset methods, we have to construct a BufferedInputStream object based on the BufferedInputStream object. import java.io.*; class bufferedOutputInputStreamEx { public bufferedOutputInputStreamEx() { byte input[]="Hello, this is text will be repeated . this text will not be read.".getBytes() ; byte output[]="".getBytes(); try { /* construct a ByteArrayOutputStream from an array of bytes */ ByteArrayOutputStream bos = new ByteArrayOutputStream(); // write byte data to the array of bytes bos.write(input); /* construct a ByteArrayInputStream from an array of bytes */ ByteArrayInputStream bis = new ByteArrayInputStream(input); /* construct a BufferdInputStream based on the ByteArrayInputStream */ BufferedInputStream in = new BufferedInputStream(bis); int ch; 12 int counter=0; /* read byte data .when a comma is read , we mark its location. When a period is read , we use reset method to go back to the comma location. This process will be repeated 3 times. after that we will break the reading process */ while ((ch= in.read()) != -1) { if (ch==',') in.mark(40); if (ch=='.') { in.reset(); counter++; } if (counter==3) break; System.out.print((char) ch); } System.out.println(); } catch(IOException e) { System.out.println("IOException "+ e.toString()); } } public static void main(String args[]) { new bufferedOutputInputStreamEx (); } } Ex11: This example shows how to write an object of type Person to a file and read it back. The class Person implements Serializable interface and is defined at the end of the source code: import java.io.*; public class objectOutputInputEx { 13 public objectOutputInputEx() { /* construct a Person object */ Person p=new Person("John","Smith"); try { /* construct an ObjectOutputStream object based on FileOutputStream */ FileOutputStream fos = new FileOutputStream("ob.dat"); ObjectOutputStream ous = new ObjectOutputStream(fos); /* write the Person object to the file ob.dat */ ous.writeObject(p); ous.flush(); ous.close(); /* construct an ObjectInputStream object based on FileInputStream */ FileInputStream fis = new FileInputStream("ob.dat"); ObjectInputStream ois = new ObjectInputStream(fis); /* read the PErson object back from the file ob.dat. Make sure to cast the object to the proper class type */ Person ob = (Person)ois.readObject(); ois.close(); System.out.println(ob.toString()); } catch(IOException ioe) { System.out.println(ioe.toString()); } catch(ClassNotFoundException cne) { System.out.println(cne.toString()); } } 14 public static void main(String args[]) { new objectOutputInputEx(); } } /* user defined class called Person. Since we intend to serialize an object of this class , it must implement Serializable interface */ class Person implements Serializable { private String fName, lName; public Person(String fn,String ln) { setFName(fn); setLName(ln); } public void setFName(String fn) { fName=fn; } public void setLName(String ln) { lName=ln; } public String toString() { return lName+" , "+fName; } } Ex12:simpleTextEditor.java This is a simple text editor application. This editor enable the user to perform the following: - open a new file for editing - open an existing file for editing - save a file to a physical driver - cut a text to the clipboard 15 - copy a text to the clipboard past a text from the clipboard change the editing area foreground change the editing area background import java.io.*; import java.awt.*; import java.awt.event.*; import javax.swing.*; public class simpleTextEditor extends JFrame implements ActionListener{ private JMenu fileMenu,editMenu,colorMenu; private JMenuItem newItem,openItem,closeItem,saveItem,cutItem,copyItem, pasteItem,backColorItem,forColorItem; private JMenuBar bar; private JTextArea inTextArea; private FileDialog getNameBox; private PrintWriter outFile; private BufferedReader inFile; private Container c; private Color color; private Box b; public simpleTextEditor(){ super("Editor Application"); bar = new JMenuBar(); setJMenuBar(bar); /* File menu, where the user can open a file , save text to a file, or exit the application */ fileMenu=new JMenu ("File"); fileMenu.setMnemonic('F'); newItem=new JMenuItem("New"); newItem.setMnemonic('N'); newItem.addActionListener(this); openItem=new JMenuItem("Open"); openItem.setMnemonic('O'); openItem.addActionListener(this); 16 saveItem=new JMenuItem("Save As"); saveItem.setMnemonic('S'); saveItem.addActionListener(this); closeItem=new JMenuItem("Close"); closeItem.setMnemonic('C'); closeItem.addActionListener(this); fileMenu.add(newItem); fileMenu.addSeparator(); fileMenu.add(openItem); fileMenu.addSeparator(); fileMenu.add(saveItem); fileMenu.addSeparator(); fileMenu.add(closeItem); bar.add(fileMenu); /* Edit menu where the user can cut, copy and paste text in the editor */ editMenu=new JMenu("Edit"); editMenu.setMnemonic('E'); cutItem=new JMenuItem("Cut"); cutItem.setMnemonic('u'); cutItem.addActionListener(this); copyItem=new JMenuItem("Copy"); copyItem.setMnemonic('C'); copyItem.addActionListener(this); pasteItem=new JMenuItem("Paste"); pasteItem.setMnemonic('P'); pasteItem.setEnabled(false); pasteItem.addActionListener(this); editMenu.add(cutItem); editMenu.addSeparator(); editMenu.add(copyItem); editMenu.addSeparator(); editMenu.add(pasteItem); bar.add(editMenu); /* color menu, where the user can change the editor background and foreground */ colorMenu=new JMenu("Color Settig"); colorMenu.setMnemonic('S'); 17 backColorItem=new JMenuItem("Change Backgroung Color"); backColorItem.addActionListener(this); colorMenu.add(backColorItem); colorMenu.addSeparator(); forColorItem=new JMenuItem("Change foreground Color"); forColorItem.addActionListener(this); colorMenu.add(forColorItem); bar.add(colorMenu); inTextArea=new JTextArea(); b=Box.createHorizontalBox(); b.add(new JScrollPane(inTextArea)); c=getContentPane(); c.setLayout(new BorderLayout()); c.add(b,BorderLayout.CENTER); setSize(750,500); show(); } // Event Handling public void actionPerformed(ActionEvent e1){ if(e1.getSource()==newItem) { inTextArea.setText(""); } else if( e1.getSource()==openItem){ String displayFileName; getNameBox=new FileDialog(this,"Display File Dialog", FileDialog.LOAD); getNameBox.show(); displayFileName=getNameBox.getFile(); if(displayFileName==null||displayFileName.equals("")) JOptionPane.showMessageDialog(this,"invalid File Name","Error", JOptionPane.ERROR_MESSAGE); else { try{ inFile=new BufferedReader(new FileReader(displayFileName)); inTextArea.setText(""); String line; 18 while((line=inFile.readLine())!=null){ inTextArea.append(line+"\n"); } inFile.close(); } catch (IOException e){ JOptionPane.showMessageDialog(this,displayFileName+e.toString(),"Error ", JOptionPane.ERROR_MESSAGE); System.exit(1); } } } else if(e1.getSource()==saveItem){ String outFileName; getNameBox=new FileDialog(this,"Display File Dialog", FileDialog.SAVE); getNameBox.show(); outFileName=getNameBox.getFile(); if(outFileName==null||outFileName.equals("")) JOptionPane.showMessageDialog(this,"invalid File Name","Error", JOptionPane.ERROR_MESSAGE); else { try{ outFile=new PrintWriter(new FileWriter(outFileName),true); outFile.print(inTextArea.getText()); outFile.close(); } catch (IOException ex){ JOptionPane.showMessageDialog(this,outFileName+ex.toString(),"Error", JOptionPane.ERROR_MESSAGE); System.exit(1); } } } 19 else if(e1.getSource()==closeItem) { System.exit(0); } else if(e1.getSource()==copyItem) { inTextArea.copy(); pasteItem.setEnabled(true); } else if(e1.getSource()==cutItem) { inTextArea.cut(); pasteItem.setEnabled(true); } else if(e1.getSource()==pasteItem) { inTextArea.paste(); } else if(e1.getSource()==backColorItem) { color=JColorChooser.showDialog(this,"Choose Color",color); if(color==null) color=Color.lightGray; inTextArea.setBackground(color); repaint(); } else if(e1.getSource()==forColorItem) { color=JColorChooser.showDialog(this,"Choose Color",color); if(color==null) color=Color.black; inTextArea.setForeground(color); repaint(); } } // main method public static void main (String args[]) { simpleTextEditor te=new simpleTextEditor(); te.addWindowListener (new WindowAdapter(){ public void windowClosing(WindowEvent e) { 20 System.exit(0); } } ); } } Ex13:createAndReadRandomAccessFileEx.java In this example you will learn how to write and read records from a random access file. First, we will write objects of type SimpleUser to the random access file. SimpleUser is a user defined class and is defined at the end of the source code. After that we will read all the records from the random access file. import java.io.*; public class createAndReadRandomAccessFile { public createAndReadRandomAccessFile() { try { /* construct a RandomAccessFile object with reading and writing permission */ RandomAccessFile m_file = new RandomAccessFile("out.dat", "rw"); /* write two records of type SimpleUser to out.dat */ SimpleUser su1 = new SimpleUser(123,"john", true,3000); su1.writeUser(m_file); SimpleUser su2 = new SimpleUser(156,"smith",false, 5000); su2.writeUser(m_file); /* read records from the random access file out.dat . */ SimpleUser su = new SimpleUser(); // find the humber of users in the random access file 21 int numberOfUsers=(int)(m_file.length()/SimpleUser.getSize()); // loop through all the records in the random access file for (int i=0;i<numberOfUsers ;i++) { m_file.seek(i * su.getSize()); su.read(m_file); System.out.println("Found: " + su.toString()); } } catch (Exception e) { } } public static void main(String args[]) { new createAndReadRandomAccessFile(); } } class SimpleUser implements Serializable { /* determine the size of the SimpleUser member variables int type is represented by 4 bytes String type is represented by 4 bytes double type is represented by 8 bytes float type is represented by 4 bytes long type is represented by 8 bytes short type is represented by 2 bytes char type is represented by 2 bytes boolean type is represented by 1 bytes */ private static final int userNumberSize = 4; // user name can have up to 15 characters private static final int userNameSize = 30; private static final int statusSize=1; private static final int salarySize=8; // memeber variables of clas SimpleUser private int userNumber; 22 private String userName; private boolean userStatus; private double userSalary; public SimpleUser(){} public SimpleUser(int uNumber, String uName,boolean uStatus,double uSalary) { setUserNumber(uNumber); setUserName(uName); setUserStatus(uStatus); setUserSalary(uSalary); } public void setUserNumber(int userNumber) { this.userNumber = userNumber; } public int getUserNumber() { return userNumber; } public void setUserName(String userName) { this.userName = userName; } public String getUserName() { return userName; } public void setUserStatus(boolean userStatus) { this.userStatus = userStatus; } public boolean getUserStatus() { return userStatus; } public void setUserSalary(double userSalary) { this.userSalary = userSalary; } public double getUserSalary() { return userSalary; } public String toString() { return "User Number:"+userNumber+" User Name:"+userName + (userStatus ? "Full Time":"Part Time")+ " User Salary: "+userSalary; } // statis method to return the size of the record in the random access file public static int getSize() { return userNumberSize + userNameSize+statusSize+salarySize; } /* method write writes a user record to the random file. The fields of the record must match the class member variables */ public void writeUser(RandomAccessFile f) throws IOException { f.writeInt( userNumber ); 23 // the size of the StringBuffer is based on the size of the userName StringBuffer buf = new StringBuffer(userName); buf.setLength(userNameSize/2); f.writeChars(buf.toString()); f.writeBoolean(userStatus); f.writeDouble(userSalary); } /* method read reads a user record from the random access file. The fields of the record must match the class member variables */ public void read(RandomAccessFile f) throws IOException { userNumber = f.readInt(); // the size of the name array is based on the size of the userName char name[] = new char[userNameSize/2], temp; for (int loop=0; loop < name.length; loop++) { temp = f.readChar(); name[loop] = temp; } /* if the user name is shorter than its maximum size, java will fill each extra character with null byte '\0'. Therefore we will replace any null byte with space. */ userName = new String(name).replace('\0', ' '); userStatus=f.readBoolean(); userSalary=f.readDouble(); } } 24