articles

Home / DeveloperSection / Articles / Java I/O: File Copy Utility

Java I/O: File Copy Utility

David Miller 1455 24-May-2016

The File Copy program accepts two command-line parameters and copies the contents of the file specified by the first parameter to the filename specified in the second parameter. If the file listed in the second parameter does not exist, it creates a new file. On the other hand, if the file does exist, its contents are destroyed before the copy operation.

Program Code                

 Below program provides the code for the File Copy program.

import java.io.*;

public class FileCopy {
                     public static void main(String[] args) {
                             int numberRead = 0;
                             InputStream readerStream = null;
                             OutputStream writerStream = null;
                             byte buffer[] = new byte[512];
                             if (args.length < 2) {
                                      System.out.println("Usage: java FileCopy file1 file2");                                     System.exit(0);                             }
                             try {
                                      readerStream = new FileInputStream(args[0]);
                             } catch (FileNotFoundException fe) {
                                      System.out.println(args[0] + " not found");
                                      System.exit(0);
                             }
                             try {
                                      writerStream = new FileOutputStream(args[1]);
                             } catch (FileNotFoundException fe) {
                                      System.out.println(args[1] + " not found");
                                      System.exit(0);
                             }
                             try {
                                      while ((numberRead = readerStream.read(buffer)) != -1) {                                                 writerStream.write(buffer, 0, numberRead);
                                      }
                             } catch (IOException ioe) {
                                      System.out.println("Error reading/writing file");                              } finally {
                                      try {
                                                readerStream.close();
                                                writerStream.close();
                                      } catch (Exception e) {
                                                e.printStackTrace();
                                      }
                             }
                             System.out.println("1 file copied!");
                     }

}
 Explanation:
Buffer and Data Sectors:

·   The main method declares a byte buffer with a size of 512. This buffer array is used for reading and writing the file data during the copy process.

·    We could have read one byte at a time, like in the previous example, and written each read byte to the new file. However, this would slow down the entire copy process for reasons given shortly.

·   It is always advisable to read and write a chunk of data at a time. For this, we created a buffer with a size of 512. Generally, buffers are allocated in multiples of 512—a typical value for disk sector size. A disk organizes its data in sectors of 512 bytes or multiples thereof.

·    Reading a single byte of data or one full sector of data requires the same amount of disk I/O processing time. Therefore, it is always efficient for a disk I/O to read/write a sector of data. Creating a buffer of 512, like in our program, results in efficient disk I/O operations

·   However, java.io package also define packages that provide in-built buffering, we will use those as we study them in the later posts. 

As before, the program now checks for the number of arguments by checking the length of the args array:

if (args.length < 2) {
System.out.println("Usage: java FileCopy file1 file2");
System.exit(0);
}

 · Next, we open an input stream on the file specified by the first command-line argument:                                        

                  readerStream = new FileInputStream(args[0]);

·  To open the output stream on the file specified by the second command-line argument, we instantiate the FileOutputStream class:

                 writerStream = new FileOutputStream(args[1]);

Next, we set up a while loop for reading and writing files:

while ((numberRead = readerStream.read(buffer)) != -1) {
writerStream.write(buffer, 0, numberRead);
}

 

·    We use the previously discussed overloaded read method of the InputStream class, which accepts the byte array argument.

·    The method returns the number of bytes read. If this number equals –1, it indicates that we have reached the end-of-file (EOF) condition.

·     The number read usually equals the buffer length, but may be less if the EOF condition occurs before the buffer is completely filled. Because the buffer length is 512 bytes, we would be reading 512 bytes in each read operation, except for the last read, which may return a number less than 512.

write method:

·     We use the write method of the OutputStream class to write the buffer contents to the file specified by the writerStream object.

·     The second parameter of the write method specifies the offset in the buffer from where the data should be written. This is always 0 in our case.

·    The third parameter specifies the number of bytes to write from the buffer. This is the number returned by our read method.

As before, we attempt to close both the files in the finally block, regardless of the outcome of the file-copy process:

·         readerStream.close();

·         writerStream.close();

As in the previous example, we need to enclose all the file operations in a try-catch block and provide error handlers for file-not-found and I/O errors.

Output:

To run this program, we would use the following command line:

C:\360\io\>java FileCopy filename1 filename2

Remember that the file-copy program will destroy the contents of the file specified by filename2 if it exists. In the preceding command, the file specified by filename1 must be present in the current working folder from where the FileCopy program is executed. The newly created file will be available in the same working folder. We may alternatively specify relative or absolute folders (path of file) for either or both filenames.


Updated 28-Nov-2017

Leave Comment

Comments

Liked By