관리 메뉴

피터의 개발이야기

[Spring] MultipartFile.transferTo(): 파일 업로드의 효율적 방법 본문

Programming/Spring

[Spring] MultipartFile.transferTo(): 파일 업로드의 효율적 방법

기록하는 백앤드개발자 2025. 2. 13. 10:58
반응형

ㅁ 들어가며

ㅇ 함께 일하는 쿠루와 이야기 하면서 대용량 파일 업로드 시 OOME을 줄이는 방법에 대해서 고민하게 되었다. 관련 내용을 찾고 공부하면서 Spring에서 제공하는 MultipartFile.transferTo() 메서드에 대해서 알게 되었다. 이 메서드는 파일 업로드 처리를 간단하고 효율적으로 만들어주는 강력한 도구였다.

 

ㅁ transferTo() 메서드란?

transferTo() 메서드는 MultipartFile 인터페이스에서 제공하는 메서드로, 업로드된 파일을 서버의 지정된 위치로 저장하는 역할을 한다. 이 메서드는 파일 데이터를 메모리에 로드하지 않고 직접 디스크로 전송하여 대용량 파일 처리에도 효율적이다.

 

ㅁ 주요 특징

  1. 간편한 사용: 단 한 줄의 코드로 파일 저장이 가능합니다.
  2. 메모리 효율성: 대용량 파일도 메모리 부하 없이 처리할 수 있습니다.
  3. 예외 처리: IOException을 던지므로, 적절한 예외 처리가 가능합니다.

간단하고 직관적인 사용법

  transferTo() 메서드는 MultipartFile 객체에 포함된 파일 데이터를 지정된 경로의 파일로 저장하는 가장 간단한 방법이다. 별도의 스트림 처리나 추가 코드를 작성하지 않아도 파일을 저장할 수 있다.

multipartFile.transferTo(new File("/path/to/save/file"));

이 한 줄로 파일 업로드 처리를 완료할 수 있어 코드가 간결해지고 유지보수가 쉽다.


성능 최적화

  transferTo() 메서드는 내부적으로 스트리밍 방식을 사용하여 파일 데이터를 처리한다. 이는 대용량 파일 업로드 시 메모리 사용량을 최소화하고, JVM 힙 메모리가 아닌 디스크를 활용하기 때문에 효율적이다. 따라서, 대용량 파일(예: 1GB 이상)을 업로드할 때도 안정적으로 작동한다. 10명이 동시에 2GB의 파일을 업로드 한다면 ? (Multipart)의 글에서 업로드 테스트를 수행하였는데, 메인 메모리를 많이 사용하지 않았다.


예외 처리 간소화

  transferTo()는 파일 저장 과정에서 발생할 수 있는 I/O 관련 예외를 자동으로 처리할 수 있도록 설계되어 있다. 개발자는 IOException과 같은 예외만 명시적으로 처리하면 된다.

try {
    multipartFile.transferTo(new File("/path/to/save/file"));
} catch (IOException e) {
    e.printStackTrace();
}

파일 이름 충돌 방지와 유연성

  파일 저장 시 UUID 등을 활용하여 고유한 파일 이름을 생성하고 저장 경로를 지정할 수 있다. 이를 통해 동일한 이름의 파일이 업로드될 때 발생할 수 있는 충돌을 방지할 수 있다.

String uniqueFileName = UUID.randomUUID().toString() + "_" + multipartFile.getOriginalFilename();
multipartFile.transferTo(new File("/path/to/save/" + uniqueFileName));

Spring의 기본 지원

  transferTo()는 Spring 프레임워크에서 기본적으로 제공되는 메서드이기 때문에 별도의 외부 라이브러리를 사용할 필요가 없다. 이는 프로젝트의 의존성을 줄이고, Spring과의 통합성을 높이는 데 기여한다.


임시 디렉토리와 연계

  Spring은 업로드된 파일을 임시 디렉토리에 먼저 저장한 후, transferTo()를 호출하면 해당 데이터를 지정된 경로로 이동한다. 이를 통해 메모리 사용량을 줄이고 안정성을 높인다.

  • 임시 디렉토리를 설정하려면 application.properties에 다음과 같은 설정을 추가할 수 있다.
    spring.servlet.multipart.location=/custom/temp/dir

간단한 사용 예제

@PostMapping("/upload")
public String uploadFile(@RequestParam("file") MultipartFile file) {
    try {
        String fileName = file.getOriginalFilename();
        File dest = new File("/path/to/save/" + fileName);
        file.transferTo(dest);
        return "파일 업로드 성공: " + fileName;
    } catch (IOException e) {
        return "파일 업로드 실패: " + e.getMessage();
    }
}

 

컨트롤러 예제

@PostMapping("/upload")
public ResponseEntity<String> uploadFile(@RequestParam("file") MultipartFile file) {
    try {
        String uploadDir = "/path/to/save/";
        String uniqueFileName = UUID.randomUUID().toString() + "_" + file.getOriginalFilename();
        file.transferTo(new File(uploadDir + uniqueFileName));
        return ResponseEntity.ok("File uploaded successfully: " + uniqueFileName);
    } catch (IOException e) {
        return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("File upload failed: " + e.getMessage());
    }
}

 

ㅁ 마무리

 MultipartFile.transferTo() 메서드는 Spring에서 파일 업로드를 처리할 때 매우 유용한 도구이다. 간단한 사용법과 높은 효율성으로 개발 생산성을 크게 향상시킬 수 있다. 다만, 파일명 중복과 보안 문제에 주의를 기울여야 하며, 적절한 예외 처리를 통해 안정적인 파일 업로드 기능을 구현할 수 있다. 

 

ㅁ 함께 보면 좋은 사이트

Spring docs - MultipartFile.transferTo

10명이 동시에 2GB의 파일을 업로드 한다면 ? (Multipart)

반응형
Comments