📚FOS Study
홈카테고리
홈카테고리
📚FOS Study

개발 학습 기록을 정리하는 블로그입니다.

바로가기

  • 홈
  • 카테고리

소셜

  • GitHub
  • Source Repository

© 2025 FOS Study. Built with Next.js & Tailwind CSS

목록으로 돌아가기
☕java/ spring-framework

FlatFileItemReader

약 3분
GitHub에서 보기

FlatFileItemReader

  • 파일 기반 배치 처리
    • 많은 시스템에서 여전히 파일 기반 데이터 처리가 중요한 역할을 한다
    • 예를 들어, 금융 거래 내역이 담긴 CSV 파일이나, 고객 데이터 파일(XML/JSON) 같은 것들이 있다.
    • 이런 데이터는 주기적으로 처리되어 시스템에 통합되거나 보고서로 만들어진다.
  • 파일 처리의 실체
    • 직접 구현 하면 이런 고통을 맛보게 된다
      • 파일 열고 닫는 것부터가 고문이다. 실수로 파일 핸들러를 놓치는 경우가 많다.
      • 대용량 파일? 한 번에 다 읽어들이면 OOM이 발생할 수 있다.
      • 예외 처리? try ~ catch 지옥에 빠져 허우적대다가 코드가 스파게티가 될 수 있다
      • 멀티스레드 환경이라고? 데드락과 레이스 컨디션의 늪에 빠져보자
      • 트랜잭션? 청크의 일부만 쓰다가 실패하면...
  • 이런 것들을 구현하는건 기계적으로 반복되는 일에 불과하다.
  • Spring Batch의 파일기반 ItemReader와 ItemWriter를 사용하면 이 모든 고통은 끝난다.
    • 파일을 열고, 읽고, 쓰고, 닫는 I/O 작업은 물론이고 데이터 파싱, 유효성 검사, 예외 처리까지.. 이놈들이 다 처리해준다

FlatFileItemReader

  • Flat File이란?
    • 단순하게 행과 열로만 구성된 파일, CSV 파일 같은 것..
    • 각 라인이 하나의 데이터
    • 다양한 구분자 지원

  • FlatFileItemReader는 플랫 파일(CSV, TSV 등)로부터 데이터를 읽어온다. 파일을 한 줄씩 읽어서 우리가 지정한 도메인 객체로 변환하여 반환한다.
  • read() 메서드의 핵심 동작은 크게 두 단계로 이뤄진다
    • 파일에서 한 줄을 읽어온다
    • 읽어온 한 줄의 문자열을 우리가 사용할 객체로 변환해 리턴한다
// FlatFileItemReader.doRead()
...
String line = readLine(); // 한 줄의 데이터를 읽어온다
...
// 문자열을 도메인 객체로 변환해 리턴한다
return lineMapper.mapLine(line, lineCount);
  • 파일에서 읽어온 한 줄의 데이터는 어떻게 객체로 변환될까?
    • 이 변환 과정에서 LineMapper라는 컴포넌트가 역할을 담당한다.
    • LineMapper는 파일의 한 줄을 우리가 사용할 객체로 변환한다.
    • Spring JDBC의 RowMapper와 유사하다고 볼 수 있다.
    • 이 LineMapper 인터페이스도 Spring Batch가 강력한 기본 구현체를 제공한다.

DefaultLineMapper : 객체 매핑의 2단계 작전

  • 1. 토큰화 작전(Tokenization)
    • 하나의 문자열 라인을 토큰 단위로 분리한다.
  • 2. 객체 매핑 작전
    • 분리된 토큰들을 도메인 객체의 프로퍼티에 매핑한다
// DefaultLineMapper.java
@Override
public T mapLine(String line, int lineNumber) throws Exception {
    FieldSet fieldSet = tokenizer.tokenize(line); // 1단계 : 문자열을 토큰화해 FieldSet 반환
    return fieldSetMapper.mapFieldSet(fieldSet); // 2단계: FieldSet을 객체로 매핑
}

1단계 : 토큰화 : 텍스트 한 줄을 의미있는 필드(token)으로 나누기

  • LineTokenizere는 파일의 한 줄을 토큰화하는 역할을 담당
    • 데이터를 토큰화하고 그 결과를 FieldSet이라는 객체로 만들어 반환
    • FieldSet은 토큰화된 데이터(tokens)와 각 데이터를 객체의 어떤 프로퍼티에 매핑할지 나타내는 프로퍼티의 이름 목록(names)을 가지고 있다.
  • 여기서 FieldSet의 프로퍼티 이름들(names)은 FlatFileItemReader를 구성할 떄 우리가 미리 지정하는 값이다
  • 한 줄의 문자열이 토큰화되어 FieldSet으로 준비

2단계 : 객체 매핑 : 토큰화된 필드들(FieldSet)을 객체에 매핑하기

  • FieldSetMapper의 mapFieldSet() 메서드는 LineTokenizer가 만든 FieldSEt 객체를 입력 받아 우리가 원하는 자바 객체로 최종 변환한다
  • 기본 설정은 BeanWrapperFieldSetMapper 이다.
    • BeanWrapperFieldSetMapper는 자바 빈 규약을 따르는 객체에 데이터를 매핑하는 구현체
    • FieldSEt의 문자열 데이터(tokens)를 객체의 프로퍼티 타입에 맞게 자동으로 변환
    • 이 때 객체의 setter를 호출해서 데이터를 설정

예제를 직접 코딩해보자

  • CSV(,로 구분하여 토크나이즈) 파일 처리
  • 같은 길이의로 토크나이즈하여 가진 파일 처리
  • 정규식으로 토크나이즈하여 파일 처리
  • 각 라인별로 패턴이 존재하는 파일 처리 (각 패턴별로 LineTokenizer, FieldSetMapper 사용)

여러 파일 읽기

  • 각 파일마다 별도의 Step을 만드는 건? 비효율의 극치
  • Spring Batch에서는 이런 요구사항을 위해 MultiResourceItemReader라는 무기를 제공
  • 어떻게 처리될까? 방법은 단순하다. 파나의 파일에서 데이터를 다 읽고 나면 다음 파일로 넘어가서 또 다시 읽는 방식이다.
  • 단 MultiResourceItemReader가 실제 파일 읽기를 수행하지는 않는다. 대신 위임 대상 ItemReader에게 실제 읽기 작업을 맡긴다.
java 카테고리의 다른 글 보기수정 제안하기
목차
  • FlatFileItemReader
  • FlatFileItemReader
  • DefaultLineMapper : 객체 매핑의 2단계 작전
  • 1단계 : 토큰화 : 텍스트 한 줄을 의미있는 필드(token)으로 나누기
  • 2단계 : 객체 매핑 : 토큰화된 필드들(FieldSet)을 객체에 매핑하기
  • 예제를 직접 코딩해보자
  • 여러 파일 읽기