Saturday, 23 June 2012

Read and Write to file line by line in Java

We can use java.io.BufferedReader and java.io.BufferedWriter classes for efficiently reading and writing text file line by line.The java.io.BufferedReader and java.io.BufferedWriter classes provide internal character buffers. Text that's written to a buffered writer is stored in the internal buffer and only written to the underlying writer when the buffer fills up or is flushed.Likewise, reading text from a buffered reader may cause more characters to be read than were requested; the extra characters are stored in an internal buffer. Future reads first access characters from the internal buffer and only access the underlying reader when the buffer is emptied.

public class BufferedReader extends Reader

The java.io.BufferedReader class is a subclass of java.io.Reader that is chained to another Reader class to buffer input.This allows more efficient reading of characters and lines.The buffer size may be specified, or the default size may be used. The default is large enough for most purposes.

There are two constructors. One has a default buffer size (8192 characters); the other requires the programmer to specify the buffer size:

public BufferedReader(Reader in, int buffer_size)
public BufferedReader(Reader in)

In general, each read request made of a Reader causes a corresponding read request to be made of the underlying character or byte stream. It is therefore advisable to wrap a BufferedReader around any Reader whose read() operations may be costly, such as FileReaders and InputStreamReaders. For example,

 BufferedReader in = new BufferedReader(new FileReader("t1.txt"));
 
will buffer the input from the specified file. Without buffering, each invocation of read() or readLine() could cause bytes to be read from the file, converted into characters, and then returned, which can be very inefficient.

BufferedReader is notable for its readLine() method that allows you to read text a line at a time.


public class BufferedWriter extends Writer


The java.io.BufferedWriter class is a subclass of java.io.Writer that is chained to another Writer class to buffer output.This allows more efficient writing of characters and lines.The buffer size may be specified, or the default size may be used. The default is large enough for most purposes.

There are two constructors. One has a default buffer size (8192 characters); the other requires the programmer to specify the buffer size:


public BufferedWriter(Writer in, int buffer_size)
public BufferedWriter(Writer in)

In general, each write request made of a Writer causes a corresponding write request to be made of the underlying character or byte stream. It is therefore advisable to wrap a BufferedWriter around any Writer whose write() operations may be costly, such as FileWriters and OutputStreamWriters. For example,


 BufferedWriter out = new BufferedWriter(new FileWriter("t1.txt"));



 
The one new method in BufferedWriter class is newLine(). This method writes a
platform-dependent line terminator string: \n on Unix, \r on the Mac, \r\n on Windows.The value of this string is taken from the system property line.separator.


Copy file line by line using BufferedReader and BufferedWriter

The following code shows how to read and write a text file line by line using BufferedReader and BufferedWriter.

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;

public class CopyFileLineByLine {

    /**
     * @param Pass
     *            Filename as command-line argument
     *            args[0]-------> Source file
     *            args[1]-------> Destination file
     * @throws IOException
     **/
    public static void main(String[] args) {
        BufferedReader br = null;
        BufferedWriter bw = null;
        String cline;
        try {
            br = new BufferedReader(new FileReader(args[0]));
            bw = new BufferedWriter(new FileWriter(args[1]));

            while ((cline = br.readLine()) != null) {
                bw.write(cline);
                bw.newLine();
            }

        } catch (IOException e) {
            System.out.println(e);
        } finally {
            try {
                br.close();
                bw.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

}

One drawback of the above code is that FileReader and FileWriter, which implicitly use the system's default character encoding.In some scenarios this default is not appropriate(for example, read an XML file with specified decoding). Here you can make use of java.io.InputStreamReader and java.io.OutputStreamWriter classes.

public class InputStreamReader
extends Reader
An InputStreamReader is a bridge from byte streams to character streams: It reads bytes and decodes them into characters using a specified charset. The charset that it uses may be specified by name or may be given explicitly, or the platform's default charset may be accepted.

public class OutputStreamWriter
extends Writer

An OutputStreamWriter is a bridge from character streams to byte streams: Characters written to it are encoded into bytes using a specified charset. The charset that it uses may be specified by name or may be given explicitly, or the platform's default charset may be accepted.

Example: Copy a file in UTF-8 format


The following code shows how to copy a text file line by line, using an explicit encoding, UTF-8

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
public class CopyFileUTF8Format {
 /**
  * @param Pass
  *            Filename as command-line argument 
  *            args[0]------> Source File
  *            args[1]------> Destination File
  * @throws IOException
  **/
 public static void main(String[] args) {
  BufferedReader br = null;
  BufferedWriter bw = null;
  String cline;
  try {
   FileInputStream fin = new FileInputStream(args[0]);
   FileOutputStream fout = new FileOutputStream(args[1]);
   br = new BufferedReader(new InputStreamReader(fin, "UTF-8"));
   bw = new BufferedWriter(new OutputStreamWriter(fout, "UTF-8"));
   while ((cline = br.readLine()) != null) {
    bw.write(cline);
    bw.newLine();
   }
  } catch (IOException e) {
   System.out.println(e);
  } finally {
   try {
    br.close();
    bw.close();
   } catch (IOException e) {
    e.printStackTrace();
   }
  }
 }
}
If you remove reference to encoding from InputStreamReader and OutputStreamWriter classes, it will still work -- the system's default encoding will simply be used instead. 

No comments:

Post a Comment