Copying a File

Problem

You need to copy a file in its entirety.

Solution

Use a pair of Streams for binary data, or a Reader and a Writer for text, and a while loop to copy until end of file is reached on the input.

Discussion

This is a fairly common operation, so I’ve packaged it as a set of methods in a class I’ve called FileIO in my utilities package com.darwinsys.util . Here’s a simple test program that uses it to copy a source file to a backup file:

import com.darwinsys.util.FileIO;

import java.io.*;

public class FileIOTest {
    public static void main(String[] av) {
        try {
            FileIO.copyFile("FileIO.java", "FileIO.bak");
            FileIO.copyFile("FileIO.class", "FileIO-class.bak");
        } catch (FileNotFoundException e) {
            System.err.println(e);
        } catch (IOException e) {
            System.err.println(e);
        }
    }
}

How does FileIO work? There are several forms of the copyFile method, depending on whether you have two filenames, a filename and a PrintWriter, and so on. See Example 9-1.

Example 9-1. FileIO.java

package com.darwinsys.util;

import java.io.*;

/**
 * Some simple file I-O primitives reimplemented in Java.
 * All methods are static, since there is no state.
  */
public class FileIO {

    /** Copy a file from one filename to another */
    public static void copyFile(String inName, String outName)
    throws FileNotFoundException, IOException {
        BufferedInputStream is = 
            new BufferedInputStream(new FileInputStream(inName));
        BufferedOutputStream os = 
            new BufferedOutputStream(new FileOutputStream(outName));
        copyFile(is, os, true);
    }

    /** Copy a file from an opened InputStream to opened OutputStream */
    public static void copyFile(InputStream is, OutputStream os, boolean close) 
    throws IOException {
        int b;                // the byte read from the file
        while ((b = is.read(  )) != -1) {
            os.write(b);
        }
        is.close(  );
        if (close)
            os.close(  );
    }

    /** Copy a file from an opened Reader to opened Writer */
    public static void copyFile(Reader is, Writer os, boolean close) 
    throws IOException {
        int b;                // the byte read from the file
        while ((b = is.read(  )) != -1) {
            os.write(b);
        }
        is.close(  );
        if (close)
            os.close(  );
    }

    /** Copy a file from a filename to a PrintWriter. */
    public static void copyFile(String inName, PrintWriter pw, boolean close) 
    throws FileNotFoundException, IOException {
        BufferedReader is = new BufferedReader(new FileReader(inName));
        copyFile(is, pw, close);
    }

    /** Open a file and read the first line from it. */
    public static String readLine(String inName)
    throws FileNotFoundException, IOException {
        BufferedReader is = new BufferedReader(new FileReader(inName));
        String line = null;
        line = is.readLine(  );
        is.close(  );
        return line;
    }

    /** The size of blocking to use */
    protected static final int BLKSIZ = 8192;

    /** Copy a data file from one filename to another, alternate method.
     * As the name suggests, use my own buffer instead of letting
     * the BufferedReader allocate and use the buffer.
     */
    public void copyFileBuffered(String inName, String outName) throws
            FileNotFoundException, IOException {
        InputStream is = new FileInputStream(inName);
        OutputStream os = new FileOutputStream(outName);
        int count = 0;        // the byte count
        byte b[] = new byte[BLKSIZ];    // the bytes read from the file
        while ((count = is.read(b)) != -1) {
            os.write(b, 0, count);
        }
        is.close(  );
        os.close(  );
    }

    /** Read the entire content of an Reader into a String */
    public static String readerToString(Reader is) throws IOException {
        StringBuffer sb = new StringBuffer(  );
        char[] b = new char[BLKSIZ];
        int n;

        // Read a block. If it gets any chars, append them.
        while ((n = is.read(b)) > 0) {
            sb.append(b, 0, n);
        }

        // Only construct the String object once, here.
        return sb.toString(  );
    }

    /** Read the content of a Stream into a String */
    public static String inputStreamToString(InputStream is)
    throws IOException {
        return readerToString(new InputStreamReader(is));
    }
}

There is a test main program included in the online source, which copies the source and class files of this program. When I ran it for testing, I followed up by using diff (a text file compare program) on the text file and its backup, and cmp (a binary compare program) on the class files. Both of these programs operate on the Unix “no news is good news” principle: if they say nothing, it is because they found nothing of significance to report, i.e., no differences.

C:javasrcio>java IOUtil
C:javasrcio>diff IOUtil.java IOUtil-java.bak
C:javasrcio>cmp  IOUtil.class IOUtil-class.bak
C:javasrcio>

But wait! Did you look closely at the body of copyTextFile( )? If you didn’t, do it now. You’ll notice that I cheated, and just reused copyDataFile( ). Well, if I’m copying a file from one place on disk to another, why go through the overhead of converting it from external form to Unicode and back? Normally you won’t have to. But if you have something like a network filesystem mounted from Windows to Unix or vice versa, better to do it a line at a time.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.133.122.127