/**
/ SLIGHTLY modified from original Lecture 10 version...
/
/ modified from "Java Examples in a Nutshell", FIRST EDITION,
/ Flanagan, O'Reilly
/ pp. 157-159
/ (LOOKS like it is the same as FileCopy in SECOND EDITION, pp. 50-51)
/
/ a strangeness: this does not always work properly under CygWin 1.0;
/ the BufferedReader doesn't handle terminal I/O when asking if an
/ existing file should be overwritten. It does work under DOS prompt
/ and sorrel, however! (???)
/
/ modified by: Sharon M. Tuttle
/ last modified: 4-9-01
**/
import java.io.*;
/**
* "This class is a standalone program to copy a file, and also
* defines a static copy() method that other programs can use
* to copy files."
**/
public class FileCopy
{
// "The main() method of the standalone program. Calls copy()."
public static void main(String args[])
{
// "Check arguments"
if (args.length != 2)
{
System.err.println("Usage: java FileCopy " +
" ");
System.exit(0);
}
// "Call copy() to do the copy, and display any error
// messages it throws"
try
{
copy(args[0], args[1]);
}
catch (IOException exc)
{
System.err.println(exc.getMessage());
}
}
/**
* "The static method that actually performs the file copy.
* Before copying the file, however, it performs a lot of
* tests to make sure everything is as it should be."
*/
// note, again, the "throws" clause here;
public static void copy(String fromName, String toName) throws IOException
{
File fromFile, toFile;
// "get File objects from Strings"
fromFile = new File(fromName);
toFile = new File(toName);
// "First make sure the source file exists, is a file,
// and is readable"
if (!fromFile.exists())
{
throw new IOException(
"FileCopy: no such source file: " + fromName);
}
if (!fromFile.isFile())
{
throw new IOException(
"FileCopy: can't copy directory: " + fromName);
}
if (!fromFile.canRead())
{
throw new IOException(
"FileCopy: source file is unreadable: " + fromName);
}
// "If the destination is a directory, use the source
// file name as the destination file name"
if (toFile.isDirectory())
{
toFile = new File(toFile, fromFile.getName());
}
// "If the destination exists, make sure it is a writeable
// file and ask before overwriting it. If the destination
// doesn't exist, make sure the directory exists and is
// writeable"
if (toFile.exists())
{
if (!toFile.canWrite())
{
throw new IOException(
"FileCopy: destination file is unwriteable: " +
toName);
}
// "Ask whether to overwrite it"
System.out.print("Overwrite existing file " + toFile.getName()
+ "? (y/n): ");
System.out.flush(); // flush the System.out buffer...
// "Get the user's response"
// (BufferedReader example!)
// p. 157: "how to read lines of text with a
// BufferedReader that reads individual characters
// from an InputStreamReader, which in turn reads
// bytes from System.in (an InputStream), which
// itself reads ketstrokes from the user's keyboard"
BufferedReader in = new BufferedReader(
new InputStreamReader(System.in));
// readLine() then returns a string, representing
// an entire line, from BufferedReader in;
String response = in.readLine();
// remove comment below to see the response read-in
// by the program;
//System.out.println("response: " + response);
// "Check the response. If not a Yes, abort the copy."
if (!response.equals("y") && !response.equals("Y"))
{
throw new IOException(
"FileCopy: existing file was not overwritten");
}
}
else
{
// "If the file doesn't exist, check if directory exists
// and is writeable. If getParent() returns null, then
// the directory is the current directory so look up the
// user.dir system property to find out what that is."
// "Get the destination directory"
// (with regard to how the file name was written ---
// was it in a path or not?)
String parent = toFile.getParent();
// ...or current working directory"
if (parent == null)
{
parent = System.getProperty("user.dir");
}
// "Convert it to a file"
File dir = new File(parent);
if (!dir.exists())
{
throw new IOException(
"FileCopy: destination directory does't exist: "
+ parent);
}
if (dir.isFile())
{
throw new IOException(
"FileCopy: destionation is not a directory: "
+ parent);
}
if (!dir.canWrite())
{
throw new IOException(
"FileCopy: destination directory is unwriteable: "
+ parent);
}
}
// whew!
// "If we've gotten this far, then everything is okay.
// So we copy the file, a buffer of bytes at a time."
// "Stream to read from source"
FileInputStream from = null;
// "Stream to write to destination"
FileOutputStream to = null;
try
{
// "Create input stream"
from = new FileInputStream(fromFile);
// "Create output stream"
to = new FileOutputStream(toFile);
// "A buffer to hold file contents"
byte[] buffer = new byte[4096];
// "How many bytes in buffer"
int bytesRead;
// "Read a chunk of bytes into the buffer, then write
// them out, looping until we reach the end of file
// (when read() returns -1). Note the combination
// of assignment and comparison in this while loop.
// This is a common I/O programming idiom."
// "Read bytes until EOF"
while ((bytesRead = from.read(buffer)) != -1)
{
// "write bytes"
to.write(buffer, 0, bytesRead);
}
}
// "Always close the streams, even if exceptions were
// thrown."
finally
{
if (from != null)
{
try
{
from.close();
}
catch(IOException exc)
{
}
}
if (to != null)
{
try
{
to.close();
}
catch(IOException exc)
{
}
}
}
}
}