Reading and Writing text files using java – part 1

Manipulating text file is the main skill that needs to be in a Java programmer. Manipulating means reading text file and writing into the another text file. Text file means just plain text file. You can create text file in your notepad/wordpad in windows. If you have mac, you can use textedit. You can also use Notepad++ or Sublime Text to create text file which both are compatible for windows and mac. There are many ways to read and write text file depending on the JDK that you are using. There are different classes that you can use from java library from those JDKs. On the other hand, it also depends on the requirements of the project and size of the file that you are trying to read and write. I will show you couple of ways to read and write text file.

Let’s start with important classes that we need to know. Most of the classes covered in the I/O Streams section are in the java.io package. Most of the classes covered in the File I/O section are in the java.nio.file package. Following are the building blocks classes of java I/O. There are a lot more in Oracle Website

  •  Path – file name with location
  •  Files – class to do operations on file
  •  Charset – for the encoding of file
  •  Scanner – allows to read file and take input from keyboard
  •  BufferedReader – readLine
  •  BufferedWriter – write new line

We should always a need to pay attention to exceptions in particular IOException and FileNotFoundException. You can catch these exceptions and provide some useful information to the user. It is always best practice to handle the exception and provide the best explanation so that user can understand the cause of the exception. Now I will show you different ways of reading and writing text file depending on the JDK that you are using.

Reading and Writing File using JDK < 7

Most entry level Java programmer use FileReader and FileWriter. FileReader and FileWriter are the widely used classes to read and write files. These classes are a bit tricky, because they use the system’s default character encoding. If we want to read and write system independent character encoding, we need look for other classes. Here are the few recommended alternatives:

  •  FileInputStream fileInput = new FileInputStream(“test.txt”);
  •  InputStreamReader inputStream = new InputStreamReader(fileInput, “Your file encoding”);
  •  FileOutputStream fileOutput = new FileOutputStream(“test.txt”);
  •  OutputStreamWriter outputStream = new OutputStreamWriter(fileOutput, “Your file encoding”);
  •  Scanner scanner = new Scanner(“test.txt”, “Your file encoding”);

You can always choose the system specific seperater by calling System.getProperty("line.separator") method for system specific line separator. It is the safest bet for the programmer to use System.getProperty(“line.seperator”). Following 3 methods take file as an argument. Following methods are used with JDK 6 and lower.

Method 1:- Using BufferedReader and InputStreamReader

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;

public class ReadWriteFile {
/**
     * Static method to read file using BufferedReader, InputStreamReader and FileInputStream
     * @param aFile
     */
    public static void readWriteFileMethod1(File aFile) {
        //reading from a file and writing into another file
        try {
            //Construct BufferedReader from InputStreamReader for fast reading
            BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(aFile)));
            BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(new File("myWriteFile.txt"))));

            String line = null;
            while ((line = br.readLine()) != null) {
                /**
                 * You can split each line here, if you need but you need to know
                 * the data splitter a head of time.
                 */
                System.out.println(line);

                //writing each line to the myWriterFile.txt
                bw.write(line);
            }

            //Closing resources. Always good idea to close resource when we don't need
            br.close();
            bw.close();
        } catch (FileNotFoundException e) {
            System.out.println(aFile +" file is not found in the path that you provided");
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    public static void main(String[] args) {
        //reading file in fileinputstreadm
        ReadFile.readFileMethod1(new File("../resources/myTest.txt"));
        System.out.println();
    }
}

Method 2: Using BufferedReader and FileReader

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.util.Scanner;

public class ReadWriteFile {
/**
     * Static method to read file using BufferedReader, FileReader
     * @param aFile
     */
    public static void readWriteFileMethod2(File aFile) {
        // Construct BufferedReader from FileReader
        BufferedReader br;
        BufferedWriter bw;
        try {
            br = new BufferedReader(new FileReader(aFile));
            bw = new BufferedWriter(new FileWriter(new File("mySecondFile.txt")));

            String line = null;
            while ((line = br.readLine()) != null) {
                /**
                 * You can split each line here if you need but you need to know
                 * the data splitter a head of time.
                 */
                System.out.println(line);
                bw.write(line);
            }

            //Closing resources. Always good idea to close resource when we don't need
            br.close();
            bw.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    public static void main(String[] args) {
        //reading file FileReader and buffered reader
        ReadFile.readFileMethod2(new File("../resources/myTest.txt"));
        System.out.println();
    }
}

Method 3: Using Scanner and FileInputStream

import java.util.Scanner;
import java.io.FileInputStream;
import java.io.FileWriter;
import java.io.PrintWriter;

public class ReadWriteFile {
    /**
     * Static method to read file using Scanner and FileInputStream
     * @param aFile
     * @throws IOException 
     */
    public static void readWriteFileMethod3(File aFile) throws IOException {

        //String builder is just to append/concat the each line to the text
        StringBuilder text = new StringBuilder();
        Scanner scanner = new Scanner(new FileInputStream(aFile), "UTF-8");
        PrintWriter pw = new PrintWriter(new FileWriter(new File("outputFile.txt")));
        while (scanner.hasNextLine()){
            /**
             * You can split each line here if you need but you need to know
             * the data splitter a head of time.
             */
            text.append(scanner.nextLine() + System.getProperty("line.separator"));
            pw.write(scanner.nextLine());
          }
        System.out.println("The text that we read: " + text);
        scanner.close();
        pw.close();
      }

    public static void main(String[] args) throws IOException {
        //reading file using scanner
        try {
            ReadWriteFile.readWriteFileMethod3(new File("../MyWebProjectCodes/resources/myTest.txt"));
        } catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
}

Above codes reads and write file line by line. You can split each line into more small pieces and put it into an array or create an object for later use or insert into the table using JDBC connection.

You might have questions, why so many ways to do the same thing? There are couples of differences depending on the thread safe and efficient. All works for reading a text file line by line though. Method 1 uses InputStreamReader and Method 2 uses FileReader. You might have a question on your mind that what’s the difference between those two classes? According to Java Doc that I retrieved from Oracle website says, “An InputStreamReader is a bridge from byte streams to character streams: It reads bytes and decodes them into characters using a specified charset.” The good about InputStreamReader is that it can handle other input streams than files, such as network connections, classpath resources, ZIP files, etc.

On the other hand, according to Java Doc, FileReader is “Convenience class for reading character files. The constructors of this class assume that the default character encoding and the default byte-buffer size are appropriate.” Having said that, FileReader does not allow you to specify an encoding other than the platform defaults encoding. If you need to read the file with specific encoding, you can’t use FileReader. In summary, InputStreamReader is always a safer choice than FileReader because of encoding and can be used in other purposes as well such as network connections, zipped files etc.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s