Open In App

How to Copy a File in Multiple Threads Using Java?

Last Updated : 31 Jan, 2024
Improve
Improve
Like Article
Like
Save
Share
Report

Copying files is a task, in programming that deals with file manipulation. Although Java offers tools, for file handling copying files can slow down our application’s performance. To optimize this process, we can take advantage of multithreading, which enables threads to work on various sections of the file.

Prerequisites:

Before diving into multithreaded file copying, ensure you have a solid understanding of the following:

Copying a file in Multiple threads using Java

Imagine a large file split into smaller chunks. By using multithreading, we can have several threads working simultaneously with each thread responsible, for reading a chunk of data, from the source file and writing it to the destination file. This parallel approach greatly cuts down on the time it takes to copy the file especially when dealing with files and high-speed disks.

Here’s a breakdown of the process:

  • To begin let’s define the paths, for the files you need to specify both the source and destination paths for copying the file.
  • Next, we need to calculate the chunk size. This involves breaking down the file into portions that can be easily handled by threads.
  • Now let’s create the threads. Each thread will have its responsibility of reading and writing a chunk of data.
  • Now for implementing chunk processing within each thread, you need to open the source file at the designated chunk offset, read the data, and write it to the corresponding chunk position in the destination file.
  • At last use thread synchronization mechanisms like join() or CountDownLatch to ensure the main thread waits for all copying threads to finish before proceeding.

Example:

In this example we will copy contents of a source file into a destination file.

Java




import java.io.*;
import java.nio.file.Files;
import java.util.concurrent.CountDownLatch;
  
public class GFG {
  
    public static void main(String[] args) throws IOException, InterruptedException {
        String sourcePath = "source.txt"; // To copy the file
        String destinationPath = "destination.txt"; // The destination file
  
        // Calculate chunk size (adjust based on file size and available threads)
        int chunkSize = 1024 * 1024; // 1 MB chunks
  
        // Get file size
        long fileSize = Files.size(new File(sourcePath).toPath());
  
        // Calculate number of chunks
        int numChunks = (int) Math.ceil((double) fileSize / chunkSize);
  
        CountDownLatch latch = new CountDownLatch(numChunks);
  
        // Create and start threads
        for (int i = 0; i < numChunks; i++) 
        {
            long start = i * chunkSize;
            long end = Math.min((i + 1) * chunkSize, fileSize);
            Thread thread = new Thread(new CopyTask(sourcePath, destinationPath, start, end, latch));
            thread.start();
        }
  
        // await() for all threads to finish
        latch.await();
  
        System.out.println("File copied successfully!");
    }
      
    static class CopyTask implements Runnable {
  
        private String sourcePath;
        private String destinationPath;
        private long start;
        private long end;
        private CountDownLatch latch;
  
        public CopyTask(String sourcePath, String destinationPath, long start, long end, CountDownLatch latch) {
            this.sourcePath = sourcePath;
            this.destinationPath = destinationPath;
            this.start = start;
            this.end = end;
            this.latch = latch;
        }
  
        @Override
        public void run() {
            try (RandomAccessFile sourceFile = new RandomAccessFile(sourcePath, "r");
                 RandomAccessFile destinationFile = new RandomAccessFile(destinationPath, "rw")) {
                sourceFile.seek(start);
                destinationFile.seek(start);
  
                byte[] buffer = new byte[1024]; // Use chunkSize here
                int bytesRead;
                while ((bytesRead = sourceFile.read(buffer)) > 0) {
                    destinationFile.write(buffer, 0, bytesRead);
                }
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                latch.countDown();
            }
        }
    }
}


Output:

If everything was correct, then output will be:

File copied successfully!

Live Example:

Output Video



Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads