Saturday, March 2, 2013

Reading and Writing Files in Java


Reading and Writing Files in Java


Java, of course, includes mechanisms to open files for reading and writing. In fact, the files can be located on the same machine where the application or applet is running, but can also be located on another machine. 

Java does not read (or write) directly from a file. Instead, all reading writing goes though streams. A Stream is a flowing sequence of characters. Java connects the stream to a file, then reads from the stream which in turn will return the data from the file. Stream classes are defined in the java.io package. The most generic ones are InputStream and OutputStream: 


Class InputStream 

public abstract class java.io.InputStream extends java.lang.Object
{   // Constructors
    public InputStream();
    // Methods
    public void close();
    public void mark(int  readlimit);
    public int read(byte  b[]);
    public void reset(); 
    public long skip(long  n);
}
Class OutputStream 
public abstract class java.io.OutputStream extends java.lang.Object
{   // Constructors
    public OutputStream();
    // Selected Methods
    public void close(); 
    public void flush(); 
    public void write(byte  b[]);
}

However, they are not very useful. For one thing, they do not have any methods to connect the stream to a file, and they can only read bytes. What is needed is a class to handle local files, and/or a class to provide more elaborate methods. Such streams are  FileInputStream and FileOutputStream, and DataInputStream and DataOutputStream. 

Class FileInputStream 
public class java.io.FileInputStream extends java.io.InputStream
{   // Constructors
    public FileInputStream(File  file); 
    public FileInputStream(String  name); 
    // Selected Methods
    public void close();
    protected void finalize();
    public int read();
    public int read(byte  b[]);
    public long skip(long  n);
}
Class FileOutputStream 
public class java.io.FileOutputStream extends java.io.OutputStream
{   // Constructors
    public FileOutputStream(File  file);
    public FileOutputStream(String  name); 
    // Selected Methods
    public void close(); 
    protected void finalize();
    public void write(byte  b[]);
    public void write(int  b); 
}

Both require a File as input to connect the stream to a file. Hence, our last class, before we can start with a few examples, is the File class. 

Class File 
public class java.io.File extends java.lang.Object
{   // Constructors
    public File(File  dir, String  name);
    public File(String  path);
    public File(String  path, String  name);
    // Selected Methods
    public boolean canRead();
    public boolean canWrite();
    public boolean exists();
    public long length();
    public boolean renameTo(File  dest);
}


Now we are ready for some examples. The first one is to simply copy one file to another file. Note that because of our security restrictions, this can only work as a Java program, not an applet. Here's the code: 
import java.io.*;

class FileCopy
{
   public static void main(String[] args) 
   {
      try 
      {
         File fileIn  = new File("source.txt");
         File fileOut = new File("target.txt");

         FileInputStream streamIn   = new FileInputStream(fileIn);
         FileOutputStream streamOut = new FileOutputStream(fileOut);

         int c;
         while ((c = streamIn.read()) != -1) 
         {
            streamOut.write(c);
         }

         streamIn.close();
         streamOut.close();
      }
      catch (FileNotFoundException e) 
      {
         System.err.println("FileCopy: " + e);
      } 
      catch (IOException e) 
      {
         System.err.println("FileCopy: " + e);
      }
   }
}
Note the line for the while loop: a character is read from the stream as an integer. It actually is the integer representation of the character, including any special characters like line feeds, tabs, etc. If the file is empty, the method stores -1 in c. Since -1 is not a valid code for any characters, it indicates the end of the file has been reached. The write method writes the character represented by the integer c to the output stream. 

Now that we are able to read and write data, we also would like more sophisticated data input methods to read the standard data types such as doubles, Strings, etc. For that, the filtered classes DataInputStream and DataOutputStream can be used.  

No comments:

Post a Comment