본문 바로가기
Java

[Java] 스레드를 활용해서 여러 파일 동시에 다운로드 받기

by teamnova 2025. 3. 6.
728x90

안녕하세요.

오늘은 스레드(Thread)를 활용해 여러 파일을 동시에 다운로드하는 프로그램을 만들어보겠습니다.

 

스레드는 하나의 프로세스 내에서 실행되는 작은 작업 단위입니다. 자바에서는 Thread 클래스를 상속받거나 Runnable 인터페이스를 구현하여 스레드를 생성할 수 있습니다. 스레드를 활용하면 여러 작업을 동시에 실행할 수 있습니다.

 

1. FileDownloader 클래스 작성

  • Thread 클래스를 상속받아 스레드로 동작합니다.
  • 생성자에서 다운로드할 파일의 URL과 로컬 저장 경로를 전달받습니다.
  • run() 메서드에서 파일 다운로드 로직을 구현합니다.
    • URL 스트림을 열어 데이터를 읽고, 로컬 파일 스트림을 열어 데이터를 씁니다.
    • 다운로드 시작과 끝의 시간을 기록하여 소요 시간을 계산합니다.
import java.io.BufferedInputStream;
import java.io.FileOutputStream;
import java.net.URL;

/**
 * FileDownloader 클래스는 지정된 URL에서 파일을 다운로드하고
 * 로컬 시스템에 저장하기 위한 기능을 제공합니다.
 */
public class FileDownloader extends Thread {
    private String fileURL;  // 다운로드할 파일의 URL
    private String savePath; // 로컬에 저장할 경로

    /**
     * FileDownloader 생성자.
     *
     * @param fileURL  다운로드할 파일의 URL
     * @param savePath 다운로드한 파일을 저장할 로컬 경로
     */
    public FileDownloader(String fileURL, String savePath) {
        this.fileURL = fileURL;
        this.savePath = savePath;
    }

    /**
     * run 메서드는 스레드에서 실행되며 파일 다운로드를 수행합니다.
     * 파일을 URL에서 읽고, 지정된 로컬 경로에 저장한 뒤,
     * 다운로드 소요 시간을 기록합니다.
     */
    @Override
    public void run() {
        try {
            // 다운로드 시작 시간을 기록하여 전체 소요 시간 측정
            long startTime = System.currentTimeMillis();

            // URL에서 입력 스트림 생성
            URL url = new URL(fileURL);
            try (BufferedInputStream inputStream = new BufferedInputStream(url.openStream());
                 FileOutputStream fileOutputStream = new FileOutputStream(savePath)) {

                // 버퍼 생성하여 파일 데이터를 읽고 씁니다.
                byte[] buffer = new byte[1024];
                int bytesRead;

                // 입력 스트림에서 데이터를 읽고 출력 스트림에 기록
                while ((bytesRead = inputStream.read(buffer, 0, 1024)) != -1) {
                    fileOutputStream.write(buffer, 0, bytesRead);
                }
            }

            // 다운로드 완료 시간을 기록하고 결과 출력
            long endTime = System.currentTimeMillis();
            System.out.println("File downloaded: " + savePath);
            System.out.println("Time taken: " + (endTime - startTime) + " ms");

        } catch (Exception e) {
            // 다운로드 중 발생할 수 있는 네트워크 또는 파일 입출력 오류 처리
            System.out.println("Error downloading file: " + fileURL);
            e.printStackTrace();
        }
    }
}

 

2. Main.java 에서 실행

  • main() 메서드에서 여러 파일의 URL과 저장 경로를 설정합니다.
  • 각 파일에 대해 FileDownloader 객체를 생성하고, start() 메서드를 호출하여 스레드를 실행합니다.
public class Main {
    public static void main(String[] args) {
        // 다운로드할 파일 URL과 저장 경로 설정
        String[] fileURLs = {
        	// 원하는 경로를 아래 예시처럼 입력하면 됩니다.
            "https://example.com/file1.jpg",
            "https://example.com/file2.jpg",
            "https://example.com/file3.jpg"
        };
        String[] savePaths = {
                "src/file/file1.jpg",
                "src/file/file2.jpg",
                "src/file/file3.jpg"
        };

        // 각 파일에 대해 스레드 생성 및 시작
        for (int i = 0; i < fileURLs.length; i++) {
            FileDownloader downloader = new FileDownloader(fileURLs[i], savePaths[i]);
            System.out.println("Starting download " + (i + 1) + "/" + fileURLs.length);
            downloader.start(); // 스레드 시작
        }

    }
}

3. 실행 결과

프로그램을 실행하면 각 파일의 다운로드가 동시에 시작되며, 다운로드 완료 후 파일 이름과 소요 시간이 다음처럼 출력됩니다.

 

또한 지정한 경로에 해당 파일이 다운로드가 된 것을 확인할 수 있습니다.