Use a pair of Stream
s 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.
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.
3.133.122.127