import java.io.*;

public class FileCopy {

	public static void copy (String source_name, String dest_name)
		throws IOException

	{
		File source_file = new File(source_name);
		File destination_file = new File(dest_name);
		FileInputStream source = null;
		FileOutputStream destination = null;
		byte[] buffer;
		int bytes_read;

		try {
			// First make sure the specified source file
			// exists, is a file, and is readable.
			if ( ! source_file.exists() || ! source_file.isFile())
				throw new FileCopyException("FileCopy: no such source file: " + source_name);
			if (!source_file.canRead())
				throw new FileCopyException("FileCopy: source file " +
					"is unreadable: " + source_name);
			
			// lf the destination exists, make sure it is a writable file
			// and ask before overwriting it. If the destination doesn't
			// exist, make sure the directory exists and is writable.
			if (destination_file.exists()) {
				if (destination_file.isFile()) {
			 		DataInputStream in = new DataInputStream(System.in);
			 		String response;
			
					if (!destination_file.canWrite())
						throw new FileCopyException("FileCopy: destination " +
								"file is unwritable: " + dest_name);
					
					// Tell the user the file already exists
					// and ask if it is okay to overwrite it.
					System.out.print("File " + dest_name +
						" aIready exists. Ovenwrite? (Y/N): ");
					
					System.out.flush();
					// Read the user's response. Note that we use
					// a DataInputStream created from System.in
					// in order to read lines rather than characters.
					response = in.readLine();
					if (!response.equals("Y") && !response.equals("y"))
						throw new FileCopyException("FileCopy: copy cancelled.");
				}
				else
					throw new FileCopyException("FileCopy: destination "
						+ " is not a fiIe: " + dest_name);
			}
			else {
				File parentdir = parent(destination_file);
				if ( ! parentdir.exists())
					throw new FileCopyException("FileCopy: destination "
						+ "directory doesn't exist: " + dest_name);

				if ( ! parentdir.canWrite())
					throw new FileCopyException("FileCopy: destination "
						+ "directory is unwritable: " + dest_name);
			}
			// If we've gotten this far, then everything is okay;
			// we can go ahead and copy the file.
			// Create an input stream from the source file and an ouput
			// stream to the destination file. Then read arrays of bytes
			// from one and write them to the other. When the read() method
			// returns -1, we've reached the end of the file and can stop.
			source = new FileInputStream(source_file);
			destination = new FileOutputStream(destination_file);
			buffer = new byte[1024];
			while(true) {
				bytes_read = source.read(buffer);
				if (bytes_read == -1) break;
				destination.write(buffer, 0, bytes_read);
			}
		}
		// No matter what happens, always close any streams we've opened.
		finally {
			if (source != null) {
				try { source.close(); }
				catch (IOException e) {};
			}
			if (destination != null)
				try { destination.close (); } catch (IOException e) {};
		}
	}
	// File.getParent() can return null when the file is specified without
	// a directory or is in the root directory.
	// This method handles those cases.
	private static File parent (File f) {
		String dirname = f.getParent ();
		if (dirname == null) {
			if (f.isAbsolute()) return new File (File.separator);
			else return new File (System.getProperty ("user.dir"));
		}
		return new File(dirname);
	}

	public static void main(String[] args) {
		if (args.length != 0)
			System.err.println ("Usage: java FileCopy " +
				"<source file> <destination file>");
		else {
			try { copy ("foo", "bar"); }
			catch (IOException e) { System.err.println (e.getMessage()); }
		}
	}
}

class FileCopyException extends IOException {
	public FileCopyException (String msg) { super(msg); }
}

