Reading and Writing Files in Java

From ChuWiki
Jump to navigation Jump to search
This page is a translated version of the page Lectura y Escritura de Ficheros en Java and the translation is 97% complete.
Outdated translations are marked like this.
Other languages:

Let's see how to read and write text and binary files in java. Also how to access these files through the Buffer of java and some other things.

Any questions about the subject or about java in general, I usually answer in the java forum.

Reading a text file in java

We can open a text file for reading using the FileReader class. This class has methods that allows to read characters. However, it is usual to want the complete lines, either because we are interested in the complete line, or to be able to analyze it later and extract fields from it. FileReader does not contain methods that allow us to read entire lines, but BufferedReader does. Fortunately, we can build a BufferedReader from the FileReader as follows:

File file = new File ("C:\\file.txt");
FileReader fr = new FileReader(file);
BufferedReader br = new BufferedReader(fr);
...
String line = br.readLine();

The opening of the file and subsequent reading can throw exceptions that must be caught. Therefore, the opening of the file and the reading must be put in a try-catch block.

In addition, the file must be closed when we finish with it, whether everything has gone well or there has been an error in reading after opening it. For this reason, a finally block is usually added to the try-catch and inside the close() of the file. Just note that the file is placed inside a FileReader and this inside a BufferedReader. They all have inside the same file opened only once. Therefore, it is enough to do close() of any of them to close the file.

The following is a complete code with everything mentioned.

import java.io.*;

class ReadFile {
   public static void main(String [] arg) {
      File file = null;
      FileReader fr = null;
      BufferedReader br = null;

      try {
         // Opening the file and creating BufferedReader to be able to
         // make a comfortable reading (it has the readLine() method).
         file = new File("C:\\file.txt");
         fr = new FileReader(file);
         br = newBufferedReader(fr);

         // Read from the file
         String line;
         while((line=br.readLine())!=null)
            System.out.println(line);
      }
      catch(Exception e) {
         e.printStackTrace();
      }finally{
         // In the finally we close the file, to make sure
         // it is closed either all works well or jumps
         // an exception.
         try{
            if( null != fr ){
               fr.close();
            }
         }catch(Exception e2){
            e2.printStackTrace();
         }
      }
   }
}

As an option to read a text file line by line, class Scanner could be used instead of FileReader and BufferedReader. See the example of Example of reading a file with Scanner

Writing a text file in java

The following code writes a text file from scratch. It writes 10 lines in the file.

import java.io.*;

public class WriteFile
{
    public static void main(String[] args)
    {
        FileWriter file = null;
        PrintWriter pw = null;
        try
        {
            file = new FileWriter("c:/test.txt");
            pw = new PrintWriter(file);

            for (int i = 0; i < 10; i++)
                pw.println("Line " + i);

        } catch(Exception e) {
            e.printStackTrace();
        } finally {
           try {
           // Again we take advantage of finally to
           // make sure the file is closed.
           if (null != file)
              file.close();
           } catch(Exception e2) {
              e2.printStackTrace();
           }
        }
    }
}

If we want to append to the end of an existing file, we simply have to set a flag to true as the second parameter of the FileWriter constructor.

 FileWriter file = new FileWriter("c:/test.txt",'''true''');

Binary files

For binary files it is done exactly the same, but instead of using the "'Reader" and the "'Writer", use the "'InputStream" and the " OutputStream". Instead of the readLine() and println(), use the read() and write() methods of array of bytes.

The following example makes a binary copy of a file

package chuidiang.examples;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;

public class FileCopy {

<div class="mw-translate-fuzzy">
   public static void main(String[] args) {
      copy ("c:/SourceFile.bin", "c:/DestinationFile.bin");
   }
</div>

   public static void copy (String OriginalFile, String CopyFile)
   {
      // They are declared outside the try because we need them inside the finally to be able to close them.
      BufferedInputStream bufferedInput = null;
      BufferedOutputStream bufferedOutput = null;

            try {
         // Open the original file for reading
         FileInputStream fileInput = new FileInputStream(originalFile);
         BufferedInputStream bufferedInput = new BufferedInputStream(fileInput);

         // The file where the copy will be made is opened
         FileOutputStream fileOutput = new FileOutputStream (fileCopy);
         BufferedOutputStream bufferedOutput = new BufferedOutputStream(fileOutput);

         // Loop to read from one file and write to the other.
         byte[] array = new byte[1000];
         int read = bufferedInput.read(array);
         while (read > 0) {
            bufferedOutput.write(array,0,read);
            read=bufferedInput.read(array);
         }

} catch (Exception e) {
         e.printStackTrace();
      } finally {
         try {
            if (null != bufferedInput) {
               bufferedInput.close();
            }
         } catch (Exception e2) {
            e2.printStackTrace();
         }
         try {
            if (null != bufferedOutput) {
               bufferedOutput.close();
         } catch (Exception e3) {
            e3.printStackTrace();
         }
      }
   }
}

The Buffered*

If we use only FileInputStream, FileOuputStream, FileReader and/or FileWriter, every time we do a read or write, it will be done physically on the hard disk. If we write or read few characters each time, the process becomes expensive and slow, with many accesses to the hard disk.

The BufferedReader, BufferedInputStream, BufferedWriter and BufferedOutputStream add an intermediate buffer. When we read or write, this class will control disk access.

  • If we are writing, it will save the data in memory until it has enough data to make the hard disk writing efficient.
  • If we want to read, the class will read a lot of data of the hard disk at once, but it only returns us what we have asked for. In the following readings it will give us what it has stored, until it needs to read again from hard disk.

This way of working makes disk accesses more efficient and the program will run faster. The difference will be more noticeable the larger the file that we want to read or write.

Random access to a file

The java class RandomAccessFile allows us to access for read or write directly to any position in the file, be it binary or text.

Related Links