Saturday, February 11, 2012

Streams and File I/O

In normal programming languages, if you want to read/write to a file, you open the file, read/write to it, the close the file.

Not so in Java.

Java has this notion of "Streams".

A Stream is something that you can read from or write to.

If you "connect" a stream to a File, you can read/write to that file.

Streams are of various types. The basic ones read/write bytes. Higher ones read/write characters. Still higher ones read/write lines (strings). And so on.

Then there are buffered streams which read/write buffer full of data at a time, which makes things more efficient.

Let us see this with an example.

Create a /data directory in your HelloWorld project, at the same level as /src.

In this directory, create a text file called "pinocchio.txt" containing the following text:

 THE ADVENTURES OF PINOCCHIO  

by C. Collodi

[Pseudonym of Carlo Lorenzini]

Translated from the Italian by Carol Della Chiesa

CHAPTER 1

How it happened that Mastro Cherry, carpenter, found a piece of wood that wept and laughed like a child.

Centuries ago there lived--

"A king!" my little readers will say immediately.

No, children, you are mistaken. Once upon a time there was a piece of wood. It was not an expensive piece of wood. Far from it. Just a common block of firewood, one of those thick, solid logs that are put on the fire in winter to make cold rooms cozy and warm.





** Leave some blank lines at the end of the text!

Suppose we wanted to read this file and then create a copy to /data/pinocchioOut.txt.

Create a class in /src/org/confucius called "FileIO.java", like this:

 package org.confucius;  

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.Reader;
import java.io.Writer;

public class FileIO {
public static void main(String[] args){
try {
File inFile = new File("data/pinocchio.txt");
File outFile = new File("data/pinocchioOut.txt");

// ----------------------------
InputStream in = new FileInputStream(inFile);
OutputStream out = new FileOutputStream(outFile);
int c;
while ((c = in.read()) != -1){
out.write(c);
}

in.close();
out.close();

// ----------------------------
Reader inR = new InputStreamReader(new FileInputStream(inFile));
Writer outW = new OutputStreamWriter(new FileOutputStream(outFile, true));

while ((c = inR.read()) != -1){
outW.write(c);
}

inR.close();
outW.close();

// ----------------------------
inR = new FileReader(inFile);
outW = new FileWriter(outFile, true);

while ((c = inR.read()) != -1){
outW.write(c);
}

inR.close();
outW.close();

// ----------------------------
BufferedReader inB = new BufferedReader(new InputStreamReader(new FileInputStream(inFile)));
BufferedWriter outB = new BufferedWriter (new OutputStreamWriter(new FileOutputStream(outFile, true)));

String s = null;
while ((s = inB.readLine()) != null){
outB.write(s);
outB.newLine();
}
inB.close();
outB.close();


// ----------------------------
inB = new BufferedReader(new FileReader(inFile));
outB = new BufferedWriter (new FileWriter(outFile, true));

s = null;
while ((s = inB.readLine()) != null){
outB.write(s);
outB.newLine();
}
inB.close();
outB.close();

// ----------------------------
File binaryFile = new File("data/binaryFile");
DataOutputStream outD = new DataOutputStream (new BufferedOutputStream (new FileOutputStream(binaryFile)));
outD.writeLong(outFile.length());
outD.close();

DataInputStream inD = new DataInputStream (new BufferedInputStream (new FileInputStream(binaryFile)));
long fileLength = inD.readLong();
System.out.println("File length = " + fileLength);


} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}




This class read pinocchio.txt in VARIOUS ways and writes to pinocchioOut.txt in VARIOUS ways!

Let us understand them all:
1. Using InputStream/OutputStream: This is the most basic Stream I/O - it reads/writes bytes

2. Using Reader/Writer: This is a character stream - it reads/writes characters.

3. Same as #2, except this time we use FileReader instead of InputStreamReader. There are always many ways to create the stream!


4. Using BufferedReader/BufferedWriter: This also is a character stream, but one that read/writes a bufferful at a time. This makes it more efficient.

5. Same as #4, but using a different way to create the stream.

6. Using DataStreams: To write primitive data type values (boolean, char, byte, short, int, long, float, and double) to a binary file, we use DataStreams. In this example, we write the length of the pinocchioOut.txt file to a binary file, then read it back.

If you right click on FileIO.java and select Run As-->Java Application, you will see new files created in /data folder: pinocchioOut.txt and binaryFile.

Needless to say, there are many more type of streams. There are ones for playing music, videos, etc.

No comments: