UCL Logo

Class FileOutput

Writing data to a file

Writing data to a file requires the following steps:

1. Decide what type of data you want to write to the file and in which order to write it. A file can contain different types of data but to read it back into a program you need to know what the types are, the order in which the data appears and the amount of data of each type.

2. Determine the file name of the file to be written.

3. Try to open the file for writing. This will connect your program to the file. Opening a file can fail (if, for instance, the file name is invalid).

4. Write the data to the file. Often this is done in a loop, to write a whole sequence of data. Writing to a file can also fail unexpectedly (for example, there may be no disk space left).

5. Close the file. This must be done to ensure that all the data you have written to the file actually gets stored in the file (data you write is typically buffered somewhere so that data is written to a file in larger lumps - this is more efficient). If a file is not closed properly you may find that data is missing from the end of the file next time you try to read it.

The following program shows how data can be written to a file using the FileOutput class listed at the end of these notes.

class FileOutputTest
{
  public static void main(String[] args)
  {
    // Create and open file.
    FileOutput out = new FileOutput("outputtest1.dat") ;

    // Write different types of value.
    // Each line must be explicitly separated
    // with a newline.
    out.writeInt(100) ;
    out.writeEndOfLine() ;

    out.writeLong(1234567L) ;
    out.writeEndOfLine() ;

    out.writeDouble(1.23456D) ;
    out.writeEndOfLine() ;

    out.writeFloat(2.34567F) ;
    out.writeEndOfLine() ;

    out.writeChar('a') ;
    out.writeEndOfLine() ;

    // With a String, the newline character can be included
    // in the String value.
    out.writeString("Hello world\n") ;

    // Must close the file when finished otherwise
    // data can be lost.
    out.close() ;
  }
}

Data is stored in a file as normal, readable characters. For example, the integer 12345 is stored as the text 12345, even though it is stored in binary format within a program. Any data file can be loaded into emacs or JEdit for viewing and editing. Typically each item of data (an integer, floating point number, text string, etc.) is stored on a separate line, as the newline is used as a marked to indicate the end of the data item.


The following class, called FileOutput, provides a number of methods to write data to a text file. Copy this class to a file called FileOutput.java and compile it. Then include a copy of the .class file in any directory where you are writing a program that needs to write to a file. This class can be used in a program at the same time as class FileInput, so you can write programs that do both file input and output. Also, like FileInput, the FileOutput class is a toy class, and would not be used in a real, robust application program.

A file can be opened for output using a statement like:

FileOutput myFile = new FileOutput("aFileName") ;

The file name can either be given directly as a quoted string or as a String variable.

When a file is opened for writing, it will either create a new file if there is no existing file with the same name or reuse an existing file. However, if an existing file is reused any data in the file will be overwritten and destroyed. Beware!

If you want to append output to the end of an existing file, without overwriting the data it already contains, then you need to set the append mode. This is easily done by providing an extra parameter when the FileOutput is object is created:

   FileOutput out = new FileOutput("outputtest1.dat",true) ;

Here the file name is followed by a second parameter, the boolean true. Any output written to the file will now be added without the existing content being overwritten. (Setting the boolean parameter to false turns off append mode, giving the default behaviour.)

The FileOutput methods are:

  • writeInt(int) - write an integer
  • writeLong(long) write a long
  • writeDouble(double) - write a double
  • writeFloat(float) - write a float
  • writeChar(char) - write a single character
  • writeString(String) - write a String
  • writeEndOfLine - write a newline character (the format of the newline will depend on what kind of machine you run the program on but should not affect the running of any program using FileInput or FileOutput).

If an error occurs when writing data, then the program will be terminated after displaying an error message.

import java.io.BufferedWriter;
import java.io.Closeable;
import java.io.File;
import java.io.FileWriter;
import java.io.Flushable;
import java.io.IOException;

/**
 * A class to enable the writing of values to a text file without having to deal with
 * exceptions.  If any errors occur, an error message is displayed and the program is
 * terminated.
 * This class is intended for learners of Java to be able to use file output before having
 * learnt about exceptions.  Once exceptions have been learnt about this class loses its
 * usefulness and the standard library classes should be used directly.
 *
 * @author Graham Roberts
 * @author Russel Winder
 * @version 2005-08-10
 */
public class FileOutput implements Closeable, Flushable
{
  /**
   * The name of the file being written to.
   */
  protected final String filename;
  /**
   * The writer to the output stream connected to the file being written to.  Use
   * BufferedWriter not Writer as we want access to the
   * newLine method.
   */
  protected final BufferedWriter writer;

  /**
   * Constructor of a FileOutput object given a file name string.
   * Setting append to true will open the file in append mode.
   */
  public FileOutput(final String filename, boolean append)
  {
    this.filename = filename;
    //  Because the FileWriter constructor can throw an IOException we have to protect its call with
    //  a try/catch block.  The BufferedWriter constructor does not throw an exception so no
    //  try/catch block is needed which is fortunate since if it had to be in a try/catch block we
    //  could not make the writer field final because of the way the Java compilers do their flow
    //  analysis.
    FileWriter fw = null;
    try
    {
      fw = new FileWriter(filename,append);
    }
    catch (IOException e)
    {
      error("Cannot open file: " + filename);
    }
    writer = new BufferedWriter(fw);
  }

  /**
   * Constructor of a FileOutput object given a File object.
   * Setting append to true will open the file in append mode.
   */
  public FileOutput(final File file, boolean append)
  {
    this(file.getName(),append);
  }

  /**
   * Constructor of a FileOutput object given a file name string.
   * If the file already exists its existing contents will be overwritten.
   */
  public FileOutput(final String filename)
  {
    this(filename,false);
  }

  /**
   * Constructor of a FileOutput object given a File object.
   * If the file already exists its existing contents will be overwritten.
   */
  public FileOutput(final File file)
  {
    this(file.getName(),false);
  }

  /**
   * Finalizor to close the file in case the using code fails to and a FileOutput
   * object gets garbage collected.
   */
  public void finalize()
  {
    close();
  }

  /**
   * Flush the associated writer.
   */
  public final synchronized void flush()
  {
    try
    {
      writer.flush();
    }
    catch (IOException e)
    {
      error("Cannot flush file: " + filename);
    }
  }

  /**
   * Close the file as it is finished with.
   */
  public final synchronized void close()
  {
    flush();
    try
    {
      writer.close();
    }
    catch (IOException e)
    {
      error("Cannot close file: " + filename);
    }
  }

  /**
   * Write an int value to a file.
   */
  public final synchronized void writeInt(final int i)
  {
    try
    {
      writer.write(Integer.toString(i));
    }
    catch (IOException e)
    {
      error("writeInteger failed to file: " + filename);
    }
  }

  /**
   * Write a long value to a file.
   */
  public final synchronized void writeLong(final long l)
  {
    try
    {
      writer.write(Long.toString(l));
    }
    catch (IOException e)
    {
      error("writeLong failed to file: " + filename);
    }
  }

  /**
   * Write a float value to a file.
   */
  public final synchronized void writeFloat(final float f)
  {
    try
    {
      writer.write(Float.toString(f));
    }
    catch (IOException e)
    {
      error("writeFloat failed to file: " + filename);
    }
  }

  /**
   * Write a double value to a file.
   */
  public final synchronized void writeDouble(final double d)
  {
    try
    {
      writer.write(Double.toString(d));
    }
    catch (IOException e)
    {
      error("writeDouble failed to file: " + filename);
    }
  }

  /**
   * Write a char value to a file.
   */
  public final synchronized void writeChar(final char c)
  {
    try
    {
      writer.write(c);
    }
    catch (IOException e)
    {
      error("writeChar failed to file: " + filename);
    }
  }

  /**
   * Write a String value to a file.
   */
  public final synchronized void writeString(final String s)
  {
    try
    {
      writer.write(s);
    }
    catch (IOException e)
    {
      error("writeString failed to file: " + filename);
    }
  }

  /**
   * Write an end-of-line marker to a file.  This writes whatever characters represent the
   * end-of-line marker on the operating system the program is run on.
   */
  public final synchronized void writeEndOfLine()
  {
    try
    {
      writer.newLine();
    }
    catch (IOException e)
    {
      error("writeEndOfLine failed to file: " + filename);
    }
  }

  /**
   * Deal with an error.  All errors a terminal with this class.
   */
  private void error(final String message)
  {
    System.err.println(message);
    System.err.println("Unable to continue executing program.");
    System.exit(1);
  }
}

Last updated: September 12, 2008

Computer Science Department - University College London - Gower Street - London - WC1E 6BT - Telephone: +44 (0)20 7679 7214 - Copyright ©1999-2011 UCL


 Search by Google