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.

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();

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();

}

}

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

{

// 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

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);

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

{

//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"));

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

{

/*

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());}

}

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());

}

}

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;

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

{

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());

}

}

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

-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);

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');

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("");