IOStreams
various sources are:
File, byte[], STDIN/Keyboard, Socket, char[], String etc
various destinations are:
File, byte[], char[], STDOUT/Monitor, Socket etc
Classes required to perform read and write on all the above said source and destinations are given in java.io package.
The two main classes given in this package are:
InputStream
OutputStream
InputStream class is having one main method called read()
OutputStream class is having one main method called write()
These methods are declared as abstract in their respective sub classes, hence both are declared as abstract.
Classes derive from InputStream class must implement read() and sub classes of OutputStream must implement write() methods
For each source device InputStream class has one sub class. To name few:
i) FileInputStream class is given to read characters/data as a stream of bytes, during each read() operation character ascii value is return to client program
ii) ByteArrayInputStream class is given to read bytes from byte[] range between 0-255, returns -1 @ the end of the stream.
iii) SocketInputStream class is having read() method to read stream of bytes from socket (n/w programming)
v) StringBufferInputStream is having read() method to read stream of bytes from String
vi) ObjectInputStream class is having readObject() that reads objects from file/network.
But the main drawback of these I/O classes are:
because of reading data byte-by-byte nunber of read() operations increases, application performance reduces.
For that one more heirarchy of InputStream classes given called FilterInputStream sub classes:
vii) DataInputStream class is having read operation to read different primitive and secondary data types such as readInt(), readDouble(), readLine()
viii) LineNumberInputStream class is having getLineNumber() that increment and return linenumber for each readLine() operation
ix) BufferedInputStream class is having read() method that is capable of reading 512 bytes of data in a single read() operation. We can increase or reduce the size of buffer by passing buffer size as argument in its constructor.
As similar to InputStream class OutputStream class is also having one-one class for each destination
i) FileOutputStream
FileOutputStream class is having one method called write() that takes ascii value of each character, type casts ascii value into char and writes it into file.
ii) ByteArrayOutputStream
Writes bytes into ByteArrayOutputStream itself and at the end when we call toByteArray(), the method returns one more byte array.
iii) SocketOutputStream
write() method writes each char ascii value into socket as it is, on the other system SocketInputStream class read() method reads ascii value and return to client, client must type cast ascii value to original char.
iv) ObjectOutputStream
This class is having one method called writeObject(Object o) that takes object of any class, converts object into stream of bytes and writes it into a file or socket
Like in InputStream, in OutputStream also one FilterOutputStream class is provided. subclasses of this class makes write operations faster.
v) DataOutputStream
This class is having one-one write method for each primitive data type and one write method for String.
vi) BufferedOutputStream
This class instance is created with default size of 512 bytes. Each call on write() method can write data upto 512 bytes at a time into its destination.
vii) PrintStream
class is having two overloaded methods called print() and println(). In these methods we can pass values of both primitive and secondary types.
Read and write data to and from file
------------------------------------
// FileReadAndWrite.java
import java.io.*;
class FileReadAndWrite
{
public static void main(String rags[]) throws Exception
{
FileInputStream fis=new FileInputStream("Threads.txt");
FileOutputStream fos=new FileOutputStream("Threads1.txt");
System.out.println(new java.util.Date());
int i=fis.read();
while(i!=-1)
{
fos.write(i);
System.out.print(i);
// Thread.sleep(1000);
i=fis.read();
}
System.out.println(new java.util.Date());
}
}
// ByteArrayStreamsTest.java
import java.io.*;
class ByteArrayStreamsTest
{
public static void main(String rags[]) throws Exception
{
// dynamic byte array
byte b1[]={-128, -1, 0, 1, 127};
ByteArrayInputStream bais=new ByteArrayInputStream(b1);
ByteArrayOutputStream baos=new ByteArrayOutputStream();
int i=bais.read();
while(i!=-1)
{
baos.write(i);
i=bais.read();
}
byte b2[]=baos.toByteArray();
int len=b2.length;
for(int j=0;j<len;j++)
{
System.out.println(b2[j]);
}
}
}
// SBTest.java
import java.io.*;
class SBTest
{
public static void main(String rags[]) throws Exception
{
String str="YogeshSingh";
StringBufferInputStream sbis=new StringBufferInputStream(str);
byte b[]=new byte[sbis.available()];
int i=sbis.read(); int counter=0;
while(i!=-1)
{
b[counter++]=i; i=sbis.read();
}
int len=b.length;
for(int j=0;j<len;j++)
{
System.out.println(b[j]+" "+(char)b[j]);
}
}
}
// DataStreamsTest.java
import java.io.*;
class DataStreamTest
{
public static void main(String rags[]) throws Exception
{
DataInputStream dis=new DataInputStream(new FileInputStream("Threads.txt"));
DataOutputStream dos=new DataOutputStream(new FileOutputStream("Threads2.txt"));
long startTime=System.currentTimeInMillis();
String line=dis.readLine();
while(line!=null)
{
dos.writeBytes(line);
// dos.writeChars(line);
line=dis.readLine();
}
long endTime=System.currentTimeInMillis();
long diffTime=endTime-startTime;
System.out.println(diffTime+" milli seconds.....");
}
}
Example on reading and writing data to and from files using BufferedInputStream and BufferedOutputStream classes
-------
// BufferedStreamsTest.java
import java.io.*;
class BufferedStreamsTest
{
public static void main(String rags[]) throws Exception
{
BufferedInputStream bis=new BufferedInputStream(new FileInputStream("1.jpg"), 1024);
BufferedOutputStream bos=new BufferedOutputStream(new FileOutputStream("1_1.jpg"), 1024);
byte b[]=new byte[1024];
System.out.println("File is in bytes : "+bis.available());
int i=new Double(Math.ceil(bis.available()/1024)).intValue();
for(int j=1;j<=i;j++)
{
bis.read(b, 0, 1024);
bos.write(b, 0, 1024);
}
}
}
ObjectInputStream and ObjectOutputStream
----------------------------------------
ObjectInput and OutputStream classes are used to serialize and deseralize class objects.
Object serialization
Object serialization is a process of converting object state (value of class instance variables is called as object state) into stream/series of bytes. The stream of bytes can be written to hard disk/into network.
With this feature in java programming language we can pass class instance state from one machine to another machine. Network programming is possible because of object serialization support in Java.
To convert object state into stream of bytes, create instance of a class, pass that object reference as argument to ObjectOutputStream class writeObject() method, writeObject() method converts state into stream of bytes and sends bytes to destination (file/network).
But before conversion writeObject() method verifies whether class is a sub class of Serializable interface or not.
If class is not a sub class of Serializable interface, then writeObject() method throws NotSerializableException. If sub class from Serializable interface then serialization takes place.
// Customer.java
class Customer
{
int cid;
String cname, address;
String ccno, pinno;
}
// CustomerSerializer.java
import java.io.*;
class CustomerSerializer
{
public static void main(String rags[]) throws Exception
{
Customer c=new Customer();
c.cid=007;
c.cname="James Bond";
c.address="Erragadda";
c.ccno="1234-5678-9012-3456";
c.pinno="7890";
ObjectOutputStream oos=new ObjectOutputStream(new FileOutputStream("customer.ser"));
oos.writeObject(c);
System.out.println("Object saved");
}
}
// CustomerDeserializer.java
import java.io.*;
class CustomerDeserializer
{
pulbic static void main(String rags[]) throws Exception
{
ObjectInputStream ois=new ObjectInputStream(new FileInputStream("customer.ser"));
Object o=ois.readObject();
Customer c=(Customer)o;
System.out.println("cid : "+c.cid);
System.out.println("cname : "+c.cname);
System.out.println("address : "+c.address);
System.out.println("ccno : "+c.ccno);
System.out.println("pinno : "+c.pinno);
}
}
During object serialization if some properties of an instance donot want to be serialized/want to be exempted from object serialization then such variables must be declared as transient.
Reader & Writer
---------------
Reader & Writer classes are similar to InputStream and OutputStream class in java.io package.
These two are super classes to many sub classes.
These classes are introduced in JDK 1.1
java.io package and Input, Output Stream classes are introduced in JDK 1.0
The speciality of these super classes is:
Reader class is having one method called read(), that reads each char from source and returns its unicode value, Writer class write() method takes unicode value of each character and writes original char to dest.
Sub classes of Reader class are:
i) BufferedReader
This class is an substitution to DataInputStream and BufferedInputStream classes in io package.
This class constructor takes any Reader class object as argument such as FileReader, CharArrayReader and StringReader.
The three important methods are:
int read()
reads char and its unicode value is returned
int read(char ch[], int offset, int len)
this method reads chars from char array passed as argument in this class constructor and writes it into another char[] passed as argument in this method
String readLine()
This method is equal to DataInputStream class readLine() method. But the difference is DIS readLine() method can read lines of code only from document which is having ascii range of chars but not unicode range of chars. Whereas BufferedReader class readLine() can read data from files which are having both ascii and unicode range of chars.
BufferedWriter
Is an substitution to DOS and BOS.
Three imp methods are:
write(int unicodeValueOfChar)
write(char ch[], int start, int offset)
write(String s, int off, int len)
newLine() after write() operation this method must be explicitly called to bring cursor to next line on destination
fush() until we call this method explicitly chars are stored in this class buffer only, flush() sends the data to destination.
CharArrayReader
---------------
CAR constr ta ch[] as arg
two imp meth are:
int read()
read(char ch[], int offset, in tlen)
read each char from source char array
and then store it into another char array dynamically
CharArrayWriter must be used
CharArrayWriter class const takes no arguments
CAW contains 3 methods:
write(int unicodeValueofChar)
write(char ch[], int offset, int len)
write(String str, int offset, int len)
read each from CAR and pass them into CAW class write() method, CAW buffers all the characters and its size automatically grows with as many number of chars as we write into it and finally if we invoke toCharArray(), this function returns char array.
Bridge classes in java.io package
---------------------------------
InputStreamReader and outputStreamWriter classes are called as bridge classes.
These classes bridges the gap between I/O streams and Reader/Writer classes.
For FileInputStream and FileOutputStream corresponding reader and writer classes are given as FileReader and FileWriter.
But what about System.in, System.out, SocketInputStream and SocketOutStream classes? Which classes must be used read character stream data from STDIN and Sockets?
Hence to convert other I/O stream classes to reader and writer classes bridge classes are given.
InputStreamReader class constructor takes any InputStream sub class object as argument. OutputStreamWriter class constructor takes any OutputStream class object as argument.
// Write a program on reading and writing data to and from files using FileReader and FileWriter objects
// FileRWDemo.java
import java.io.*;
class FileRWDemo
{
public static void main(String rags[]) throws Exception
{
FileReader fr=new FileReader("Threads.txt");
FileWriter fw=new FileWriter("Threads3.txt");
int i=fr.read();
while(i!=-1)
{
System.out.print((char)i);
fw.write(i);
i=fr.read();
}
// fw.flush();
// fw.close();
}
}
// Use BufferedReader and BufferedWriter
// BufRWDemo.java
import java.io.*;
class BufRWDemo
{
public static void main(String rags[]) throws Exception
{
BufferedReader br=new BufferedReader(new InputStreamReader(new FileInputStream("Threads.txt")));
BufferedWriter bw=new BufferedWriter(new OutputStreamWriter(new FileOutputStream("Threads4.txt")));
String line=br.readLine();
while(line!=null)
{
System.out.println(line);
bw.write(line);
bw.newLine();
line=br.readLine();
}
}
}
The main limitation of FileOutputStream and FileWriter classes is that they will always override existing file content with new content.
To perform insert and append operations RandomAccessFile class must be used.
The important methods of RAF are:
long getFilePointer()
long length()
read() method for each primitive data type
seek(long pos)
setLength(long newLength)
skipBytes(int n)
write() method for each primitive data type
RandomAccessFile constructor takes fileName and filemode as arguments ("r", "rw").
// Write a program on RAF
// RAF.java
import java.io.*;
import java.util.*;
class RAFTest
{
public static void main(String rags[]) throws Exception
{
RandomAccessFile raf=new RandomAccessFile("students.csv", "rw");
Scanner sc=new Scanner(System.in);
System.out.println("Enter SID : ");
int sid=sc.nextInt();
System.out.println("Enter SName : ");
String sname=sc.next();
System.out.println("Enter Email : ");
String email=sc.next();
System.out.println("Enter Address : ");
String address=sc.next();
String record=sid+","+sname+","+email+","+address+"\n";
long len=raf.length();
raf.seek(len);
raf.writeBytes(record);
System.out.println("mydb> 1 Record inserted");
}
}
// Write a program to update address of student record
// RAFUpdate.java
import java.io.*;
import java.util.*;
class RAFUpdate
{
public static void main(String rags[]) throws Exception
{
Scanner sc=new Scanner(System.in);
int sid=sc.nextInt();
String address=sc.next();
RandomAccessFile raf=new RandomAccessFile("students.csv","rw");
RandomAccessFile raf1=new RandomAccessFile("temp.csv", "rw");
String line=raf.readLine();
while(line!=null)
{
StringTokenizer st=new StringTokenizer(line, ",");
int sid1=Integer.parseInt(st.nextToken());
if(sid1==sid)
{
raf1.writeBytes(sid+","+st.nextToken()+","+st.nextToken()+","+address+"\n");
}
else
{
raf1.writeBytes(sid+","+st.nextToken()+","+st.nextToken()+","+st.nextToken()+"\n");
}
line=raf.readLine();
}
raf.close(); raf1.close();
// File f=new File("temp.csv");
// f.renameTo(new File("students.csv"));
File f1=new File("temp.csv");
File f2=new File("students.csv");
f2.delete();
f1.renameTo(f2);
}
}