Introduction to Java I/O : JDK has two sets of I/O packages: the Standard I/O (in package java.io), introduced since JDK 1.0 for stream based I/O, and, the New I/O (in package java.nio), introduced in JDK 1.4, for more efficient buffer based I/O.

Concept of file:   So far we have used variables and arrays for storing data inside a program. This possesses the following problems.

  1. The data is lost either when a variable goes out of scope of when the program is terminated. That is, the storage is temporary.
  2. It is difficult to handle large volumes of data using variables and arrays.

  A file is a collection of related records placed in a particular area on the disk. A record is composed of several fields and a field is a group of characters. The characters in Java are Unicode characters composed of two bytes, each byte containing eight binary digits, 0 and 1.

Storing and managing data using file is known as file processing which includes tasks such as creating files, updating files and manipulation of data. Java supports many powerful features for managing input and output of data using files. The process of reading and writing objects is called object serialization.

Concept of Streams:  Java uses the concept of streams to represent the ordered sequence of data, a common characteristic shared by all the input/output devices. A stream represents a uniform, easy to use, object oriented interface between the program and input/output devices.

A stream in Java is a path along which data flows. It has a source of data and a destination for that data.

Java streams are classified into two basic types, namely, input stream and output stream. An input stream extracts (reads) data from source (file) and sends it to the program. Similarly, an output stream takes data from the program and sends (writes) it to the destination (file).

File and Directory in Java

File: Files are a primary source and destination for data within many programs. Files are still a central resource for storing persistent and shared information. A directory in Java is treated simply as a File with one additional property- a list of filenames that can be examined by the list()  method.

The following constructors are used to create a FIle object

File(String directroyPath)

File (String directoryPath, String Filename)

File(File dirObj, String filename)

File (URI uriObj)

File defines many methods that obtain the standard properties of a File object. The following program shows use of different methods.

import java.io.File;

public class FileDemo {

    static void display(String s){

        System.out.println(s);

    }

    public static void main(String[] args) {

        File f = new File("E:\\janak\\operation\\MathOperation.java");

        display("File Name"+" "+f.getName());

        display("File Path"+" "+f.getPath());

        display("Parent "+" "+f.getParent());

        display(f.exists()?"File Exists":"File does not exists");

        display(f.canWrite()?"File is writable":"File is not writable");

        display(f.canRead()?"File is readable":"File is not readable");

        System.out.print("f is directory");

        display(f.isDirectory()?"true":"false");

        display("File last modified "+f.lastModified());

        display("File size "+" "+f.length()+" bytes");       

    }   

}

 

The output of the above program is:

File Name MathOperation.java

File Path E:\janak\operation\MathOperation.java

Parent  E:\janak\operation

File Exists

File is writable

File is readable

f is directory false

File last modified 1454208277396

File size  409 bytes

Here are some other methods that are useful

Void deleteOnExit() Removes the file associated with the invoking  object when the Java Virtual Machine terminating
Boolean isHidden() Return true if the invoking file is hidden and false otherwise
Boolean setLastModofied(long mills) Sets the tile stamp on the invoking file to that specified by milliseconnds, which is the number of milliseconds from Jan, 1 1970.
Boolean setReadOnly() Sets the invoking file to read only.

Directories

A directory is a File that contains a list of other files and directories. When we create a File object and it is a directory, the isDirectory () method will return true. We can call list() methods on that object to extract the list of other files and directories inside.  A directory in Java is treated simply as a File with one additional property- a list of filenames that can be examined by the list() method.

import java.io.File;

public class DirList {

    public static void main(String[] args) {

        String dirname = "E:/janak/operation";

        File f1 = new File(dirname);

        if(f1.isDirectory()){

            String s[] = f1.list();

            for(int i=0;i<s.length;i++){

                File f = new File(dirname+ "/"+s[i]);

                if(f.isDirectory()){

                    System.out.println(s[i]+" is a directory");

                }

                else

                {

                    System.out.println(s[i]+" is a file");

                }

            }

        }

        else

        {

            System.out.println(dirname+" is not a directory");

        }

    }   

}

 

The output of above program is

ArithmeticOperation.class is a file

ArithmeticOperation.java is a file

MathOperation.class is a file

MathOperation.java is a file

SDV is a directory

Using FilenameFilter

Sometime we want to limit the number of files returned by the list() method to include only those files that match a certain filename patterns or filters. To do this, we use second form of list() shown below:

String[] list(FilenameFilter FFObj)

In this form, FFObj is an object of a class that implements the FilenameFilter interface.

The following program shows listing files with some criteria:

import java.io.*;

import java.io.File;

class OnlyExt implements FilenameFilter{

    String ext;

    public OnlyExt(String ext){

        this.ext = "."+ext;

    }

    public boolean accept (File dir, String name){

        return name.endsWith(ext);

    }

}

public class DirListDirectory {

    public static void main(String[] args) {

        String dirname = "E:/janak/operation";

        File f1 = new File(dirname);

        FilenameFilter only = new OnlyExt("java");

        String s[] = f1.list(only);

        for(int i=0;i<s.length;i++)

        System.out.println(s[i]);        

    }

}

 

The output of above program is:

ArithmeticOperation.java

MathOperation.java

Example: The following program recursively lists the given directory

import java.io.File;

public class ListDirectoryRecursive {

    public static void main(String[] args) {

        File dir = new File("C:");

        listRecursive(dir);

    }

    public static void listRecursive(File dir){

        if(dir.isDirectory()){

            File[] items = dir.listFiles();

            for(File item:items){

                System.out.println(item.getAbsoluteFile());

                if(item.isDirectory())

                    listRecursive(item);

            }
}
}
}

 

The output of the above program is:

run:

C:\Users\Dell\Documents\NetBeansProjects\operation\applet.policy

C:\Users\Dell\Documents\NetBeansProjects\operation\build

C:\Users\Dell\Documents\NetBeansProjects\operation\build.xml

C:\Users\Dell\Documents\NetBeansProjects\operation\manifest.mf

C:\Users\Dell\Documents\NetBeansProjects\operation\nbproject

C:\Users\Dell\Documents\NetBeansProjects\operation\src

C:\Users\Dell\Documents\NetBeansProjects\operation\sum.dat

 

Stream I/O in java.io Package

Programs read inputs from data source such as, keyboard, file, network, memory buffer, or other program and write outputs to data sinks for example, display console, file network, memory buffer, or another program. In Java standard I/O, inputs and outputs are handled by the so called streams.  The Java program receives data from a source by opening an input stream and sends data to a sink by opening an output stream. All Java I/O streams are one way. Java has two streams:

  • Byte Streams and
  • Character Streams.

The Byte Streams: Byte streams provide a convenient means for handling input and output bytes. The bytes mean reading or writing binary data of 8 bit bytes. Some common Byte Stream classes are:

FileInputStream, FileOutStream, DataInputStream, DataOutputStream, BufferedInputStream, BufferedOutputStream, ByteArrayInputStream.

Reading and writing Files Using Byte Streams: Generally, file handling mechanism involves following steps:

  • Opening files on which you want to read, write or manipulate
  • Perform Read/Write operations
  • Close the files

Java provides a number of classes and methods that allows reading and writing files. Two of the most often used stream classes are:

  • FileInputStream class creates an InputStream that you can use to read bytes from a file.
  • FileOutputStream creates an OutputStream that you can use to write bytes to a file.

The following program copies the content of one file to another file using byte stream.

import java.io.*;

public class CopyBytes {

    public static void main(String[] args) {

        FileInputStream in = null;

        FileOutputStream out = null;

        int c;

        try{

            in = new FileInputStream("e:\\java\\Sample.java");

            out = new FileOutputStream("e:\\java\\Sample1.java ");

            while((c=in.read())!=-1){

                out.write(c);

                System.out.print((char)c);

            }

            in.close();

            out.close();

        }catch(IOException e){

            System.out.println("Error"+e);

        }

    }   

}

 

Appending Content: Appending the content of one file to another file means attaching the content to the end of the file. This program copies the content of Sample.java file and appends it in the file testoutput.txt;

import java.io.*;

public class AppendFileDemo {

    public static void main(String[] args){

        int c;

        try{

            FileInputStream fis = new FileInputStream ("e:\\java\\testinput.txt");

            FileOutputStream fos = new FileOutputStream ("e:\\java\\testoutput.txt",true);

            while((c=fis.read())!=-1){

                fos.write(c);

                System.out.print((char)c);

            }

            fis.close();

            fos.close();

        }catch(IOException e){

            System.out.println ("Error"+e);

        }           

        }

    }

 

Reading from keyboard

DataInputStream and DataOutputStream classes: DataInputStream class extends FilterInputStream class and implements DataInput interface. It has some methods used to read the data:

readShort()  , readInt(), readChar() , readLine() , readLong() , readFloat() , readBoolean().

Similarly DataOutputStream extends FilterOutputStream and implements DataOutput interface. It also define some methods to write data as writeShort (), writeInt () and so on.

The Character Streams

Character stream provides a convenient means for handling input and output of characters. They use Unicode and therefore can be internationalized. Character streams are more efficient than byte stream. Character streams classes are defined by using the two classes Reader and Writer. These abstract classes handle Unicode character streams. The abstract classes Reader and Writer define key methods that the other stream classes implement. Two of the most important methods are:

  • read() : This method is used to read characters of data.
  • write () : This method is used write characters of data.

The classes of character based IO are as follows:

FileReader

The FileReader is subclass of Reader that you can use to read the contents of a file.  We use following constructors:

  • FileReader(String filePath)
  • FileReader(File fileObject)

The following program demonstrates Filereadder, the program reads the same source code and prints in standard output stream

import java.io.*;

public class FileReaderDemo {

    public static void main(String[] args)throws IOException {

        FileReader fr = new FileReader("C:\\Users\\Dell\\Documents\\NetBeansProjects\\operation\\src\\FileReaderDemo.java");

        BufferedReader br = new BufferedReader(fr);

        String s;

        System.out.println("The content of the read file is...");

        while((s=br.readLine())!=null){

            System.out.println(s);

        }

        fr.close();

    }   

}

 

The output of the above program is:

import java.io.*;

public class FileReaderDemo {

    public static void main(String[] args)throws IOException {

        FileReader fr = new         FileReader("C:\\Users\\Dell\\Documents\\NetBeansProjects\\operation\\src\\FileReaderDemo.java");

        BufferedReader br = new BufferedReader(fr);

        String s;

        System.out.println("The content of the read file is...");

        while((s=br.readLine())!=null){

            System.out.println(s);

        }

        fr.close();

    }   

}

 

FileWriter

FileWriter class creates Writer that we can use to write a file. The most commonly used constructors are:

FileWriter(String filePath);

FileWriter(String filePath, boolean b);

FileWriter(String fileObj);

FileWriter(String fileObj, boolean append);

The following program copies the content of one file to another file using FileReader and FileWriter character stream.

import java.io.*;

public class CopyCharacter {

    public static void main(String[] args) {   

    FileReader infile = null;

    FileWriter outfile = null;

    int c;

    try{

    infile = new FileReader("e:\\java\\test.txt");

    outfile = new FileWriter("testout.txt");

    while((c=infile.read())!=-1){

        outfile.write(c);

            System.out.print((char)c);

    }

    infile.close();

    outfile.close();

}catch(IOException e){

            System.out.println (e);

}

System.out.println ("Copying complete");




}   

}

 

Predefined Streams: The java.lang package defined a class called System which contains three predefined stream variables in, out and err. These fields are declared as public and static within the System.

  • out: Refers to the standard output stream and it is an object of type PrintStream. By default this is a console.
  • in: Refers to standard input, which is the keyboard by default. It is an object of type InputStream.
  • err: Refers to standard err Stream.

Reading Console Input

To reading the console input character oriented streams is more efficient rather than byteStream, you may use any one byte stream or character streams. DataInputStream is used for byte steam like.

DataInputStream dis = new DataInputStream (System.in);

And InputStreamReader is used in character stream with System.in. To enhance performance we can use BufferedReader class

BufferedReader br = new BufferedReader (new InputStreamReader (System.in));

The following program reads two numbers from keyboard and displays the sum on screen.

import java.io.*;

public class UserDataInput {

    public static void main(String[] args) {

        int x,y,sum;

        try{

            BufferedReader br = new BufferedReader (new InputStreamReader (System.in));

            System.out.println("Enter x");;

            x = Integer.parseInt(br.readLine());

            System.out.println("Enter y");

            y = Integer.parseInt(br.readLine());

            sum = x+y;

            System.out.println("The sum is "+sum);

        }catch(IOException e){

            System.out.println(e);

        }

    }   

}

 

The output of the above program is:

run:

Enter x

100

Enter y

200

The sum is 300

Reading Console Input and writing to file

The following program reads data from keyboard and writes to file using DataInputStream and FileOutputStream

import java.io.*;

public class ReadFromKeyWriteFile {

public static void main(String[] args) {

        int c;

        try{

            DataInputStream dos = new DataInputStream(System.in);

            FileOutputStream fos = new FileOutputStream("testing.txt");

            System.out.println("Write 'q' at end , To end");

            do{

                c = dos.read();

                fos.write(c);

            }while(c!='q');

        }catch(IOException e){

            System.out.println(e);

        }

    }

}

 

Concatenation of Files: It is possible to combine two or more input streams (files) into a single InputStream (file), this process is known as concatenation of file and is achieved using the SequenceInputStream class.

The following program shows concatenation of files

import java.io.*;

public class ConcatenateFiles  {

    public static void main(String[] args) throws IOException {

        int ch;

        FileInputStream file1 = new FileInputStream("e:\\\\java\\test1.txt");

        FileInputStream file2 = new FileInputStream("e:\\\\java\\test2.txt");

        SequenceInputStream file3 = new SequenceInputStream(file1,file2);

        FileOutputStream fos = new FileOutputStream("text3.txt");

        BufferedInputStream inBuffer = new BufferedInputStream(file3);

        BufferedOutputStream outBuffer = new BufferedOutputStream(System.out);

        while((ch=inBuffer.read())!=-1){

            outBuffer.write((char)ch);

            fos.write(ch);

        }

        inBuffer.close ();

        outBuffer.close ();

        file1.close ();

        file2.close ();

        fos.close();      

       }   

}

 

Random Access File: All the I/O streams covered so far are one way steams. Furthermore, they are all sequential access streams, meant for reading and writing data sequentially. Nonetheless, it is sometimes necessary to read a file record directly as well as modifying existing records or inserting new records. The class RandomAccessFile provides supports for non-sequential, direct or random access to a disk file. RandomAccessFile is a two way stream, supporting both input and output operations in the same stream.

RandomAccessFile can be treated as huge byte array. We can use a file pointer of type long, similar to array index, to access individual byte or group of bytes in primitive types. The file pointer is located at 0 when the file is opened. It advances automatically for every read and write operation by the number of bytes processed.

In constructing a RandomAccessFile, we can use flags ‘r’ or ‘rw’ to indicate whether the file is “read only” or “read-write” access.

  • RandomAccessFile f1 = new RandomAccessFile(“filename”, “r”);
  • RandomAccessFile f2 = new RandomAccessFile(“filename”, “rw”);

Let us consider the following methods

import java.io.*;

public class RandomAcess {

public static void main(String[] args) {

RandomAccessFile rfile =null;

try{

            rfile = new RandomAccessFile("rend.dat","rw");

            rfile.writeChar('X');

            rfile.writeInt(555);

            rfile.writeDouble(45.34);

            rfile.seek(0);

            System.out.println(rfile.readChar());

            System.out.println(rfile.readInt());

            System.out.println(rfile.readDouble());

            rfile.seek(2);

            System.out.println(rfile.readInt());

            rfile.seek(rfile.length());

            rfile.writeBoolean(true);

            rfile.seek(4);

            System.out.println(rfile.readBoolean());

        }catch(IOException e){

            System.out.println(e);

        }       

    }   

}

 

The output of the above program is:

Run:

X

555

45.34

555

true

Object Serialization and Object Streams

Serialization is process of writing the state of an object to a byte stream. This is useful when you want to save the state of our program to a persistent storage area such as a file. Only an object that implements the Serializable interface can be saved and restored by the serializable facilities. The variables that are declared as transient and static are not saved by serialization facilities.

Object Streams

The Object Streams ObjectOutputStream and ObjectInputStream classes are used to save the object’s state in a file. For this, we first need to open an ObjectOutputStream object.

ObjectOutputStream out = new ObjectOutputStream (new FileOutputStream (“Employee.dat”));

Consider the following program:

import java.io.*;

class Student implements Serializable{

    private int roll;

    private String name;

    private String address;

    private String phone;

    private String semester;

    private String level;

    public Student(){}

    public Student(int r, String n, String add, String ph, String sem, String l){

        roll = r;

        name = n;

        address = add;

        phone = ph;

        semester = sem;

        level = l;

    }

    public int getRoll(){return roll;}

    public String getName(){return name;}

    public String getAddress(){return address;}

    public String getPhone(){return phone;}

    public String getSemester(){return semester;}

    public String getLevel(){return level;}      

}

public class Studentcall {

    public static void main(String[] args) throws IOException{

        Student s1 = new Student(1,"kamal Raj Joshi","Patan","9849294787","BIM V","Bachelor");

        Student s2 = new Student(1,"Bibek Raj Joshi","Baitadi","9849785546","M.Sc V","Master");

        Student s3 = new Student(1,"Himal Raj Joshi","Darchula","9849331288","I.Sc V","Intermediate");

        ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("student.txt"));

        out.writeObject(s1);

        out.writeObject(s2);

        out.writeObject(s3);

        ObjectInputStream in = new ObjectInputStream(new FileInputStream("student.txt"));

        try{

            s1 = (Student)in.readObject();

            s2 = (Student)in.readObject();

            s3 = (Student)in.readObject();

        }catch(ClassNotFoundException e){

            e.printStackTrace();

        }

        System.out.println("The data in file are:Object first");

        System.out.println("Object first");

        System.out.println("Roll no = "+s1.getRoll()+"\nName ="+s1.getName()+"\n Address = "+s1.getAddress()+"\nPhone no = "+s1.getPhone()+"\nSemester ="+s1.getSemester()+"\nLevel="+s1.getLevel());

        System.out.println("The data in file are:Object first");

        System.out.println("Object second");

        System.out.println("Roll no = "+s2.getRoll()+"\nName ="+s2.getName()+"\n Address = "+s2.getAddress()+"\nPhone no = "+s2.getPhone()+"\nSemester ="+s2.getSemester()+"\nLevel="+s2.getLevel());

        System.out.println("The data in file are:Object first");

        System.out.println("Object third");

        System.out.println("Roll no = "+s3.getRoll()+"\nName ="+s3.getName()+"\n Address = "+s3.getAddress()+"\nPhone no = "+s3.getPhone()+"\nSemester ="+s3.getSemester()+"\nLevel="+s3.getLevel());

    }   

}

 

The output of the above program is:

run:

The data in file are:Object first

Object first

Roll no = 1

Name =kamal Raj Joshi

 Address = Patan

Phone no = 9849294787

Semester =BIM V

Level=Bachelor

The data in file are:Object first

Object second

Roll no = 1

Name =Bibek Raj Joshi

 Address = Baitadi

Phone no = 9849785546

Semester =M.Sc V

Level=Master

The data in file are:Object first

Object third

Roll no = 1

Name =Himal Raj Joshi

 Address = Darchula

Phone no = 9849331288

Semester =I.Sc V

Level=Intermediate

Input via java.util.Scanner

The JDK 1.5 introduced java.util.Scanner class, which simplifies formatted text input from input source. As the name implies Scanner is simple text scanner which can parse the input text into primitive types and strings using regular expressions. It first breaks the text input into tokens using a delimiter pattern, which are by default the white spaces. The tokens may then be converted into primitive values of different types using the various nextXXX () methods. We can also use the hasNextXXX () methods to check for the availability of a desired input.

The commonly used constructors are as follows:

public Scanner (File source) throws FileNotFoundException

public Scanner (File source, String charsetName) throws FileNotFoundException

public Scanner (FileInputStream source)

public Scanner (InputStream source, String charsetName)

public Scanner (String source)

For example:

Constructing a Scanner to parse an int from keyboard.

Scanner input = new Scanner(System.in);

int i = input.nextInt()

Constructing a Scanner to parse all doubles from a disk file

Scanner in2 = new Scanner(new File(“in.txt));

while(in2.hasNextDouble()){

double d = in.nextDouble();

}

// Construct

Scanner in3 = new Scanner (“This is the input text string”);

while (in3.hasNext ()){

String s = in.next();

}

The most common use of Scanner is to read primitive types and String form the keyboard (System.in), as follows:

import java.util.Scanner;

public class TestScannerSystemIn {

    public static void main(String[] args){

        Scanner in = new Scanner (System.in);

        System.out.println ("Enter an Integer");

        int x = in.nextInt();

        System.out.println("You entered "+x);

        System.out.println("Enter a floating point number");

        double d = in.nextDouble();

        System.out.println("You entered "+d);

        in.nextLine();//Flush the enter before reading the next line

        System.out.println ("Enter your name");

        String name = in.nextLine();

        System.out.println("Hello ! "+name);

    }   

}

 

The output of the above program is:

run:

Enter an Integer

11

You entered 11

Enter a floating point number

22.22

You entered 22.22

Enter your name

Bijay Ghimire

Hello  ! Bijay Ghimire

Some worked out Example

  1. Write a CUI program to accept two numbers and save its sum in file “sum.dat”.
import java.io.*;

public class ReadNumberWriteFileSum {

    public static void main(String[] args){

        int x,y,sum;

        String str;

        try{

            DataOutputStream dos = new DataOutputStream(new FileOutputStream("sum.dat"));

            DataInputStream dis = new DataInputStream(System.in);

            System.out.println("Enter x");

            x = Integer.parseInt(dis.readLine());

            System.out.println("Enter y");

            y = Integer.parseInt(dis.readLine());

            sum = x+y;

            str = Integer.toString(sum);

            dos.writeBytes("The Sum is = "+str);

            dos.close();

        }catch(IOException e){

            System.out.println(e);

        }

    }   

}

 

 

import java.io.*;

public class AppendDemo {

    public static void main(String[] args){

        RandomAccessFile rFile;

        BufferedReader br;

        String s;

        try{

            rFile = new RandomAccessFile("names.txt","rw");

            br = new BufferedReader(new InputStreamReader(System.in));

            rFile.seek(rFile.length());

            System.out.println("Enter one line string to be appended");

            s = br.readLine();

            rFile.writeBytes(s);

            rFile.close();

            System.out.println("......Appending .....Success...");

        }catch(IOException e){

            System.out.println(e);

        }       

    }   

}

 


Didn't Find Any Subjects/Contents?

Click on the contribute button to contribute subjects materials on Study Notes Nepal.

Contribute

Leave a Reply

Your email address will not be published. Required fields are marked *


Join Our Facebook Community Group

Study Notes Nepal