[Spring Batch] 스프링 배치에서 csv, txt 파일 읽기(FlatFileItemReader)

스프링 배치에서 평면 파일(CSV, TXT) 파일을 읽는 방법은 FlatFileItemReader 객체를 설정하는 것 입니다. 최신 스프링 배치에서는 Builder 패턴을 사용하여 매우 직관적으로 코드를 작성 할 수 있습니다.

CSV 파일 읽기(구분자 방식 – Delimited)

가장 흔한 방식 입니다. 쉼표(,) 등으로 구분된 파일을 읽습니다.

샘플 파일

이름,나이,이메일
김철수,30,chulsu@example.com
이영희,28,younghee@test.com
박지훈,35,jihoon@company.com

스프링 배치 코드

  • .linesToSkip(1) : 보통 CSV 첫 줄은 데이터가 아닌 헤더이므로 생략 합니다.
  • .names(…) : 구분자로 쪼개진 데이터에 순서대로 이름을 붙입니다. 이 이름이 targetType의 필드명과 일치해야 데이터가 맵핑 됩니다.
  • .targetType(…) : 스프링 배치가 내부적으로 BeanWrapperFieldSetMapper를 생성하여 names에서 지정한이름과 동일한 객체의 필드에 값을 자동으로 넣어줍니다.
import org.springframework.batch.item.file.FlatFileItemReader;
import org.springframework.batch.item.file.builder.FlatFileItemReaderBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ClassPathResource;

@Configuration
public class CsvReaderConfig {

    @Bean
    public FlatFileItemReader<Person> csvItemReader() {
        return new FlatFileItemReaderBuilder<Person>()
                .name("csvItemReader") // 리더의 이름 지정
                .resource(new ClassPathResource("input.csv")) // 읽어올 파일 위치
                .linesToSkip(1) // 첫 번째 줄(헤더)은 건너뛰기
                .delimited() // 구분자 방식(기본값: 쉼표) 사용
                .delimiter(",") // (선택사항) 탭(\t)이나 파이프(|) 등 커스텀 가능
                .names("name", "age", "email") // 읽어들인 데이터에 컬럼명 부여
                .targetType(Person.class) // 변환할 객체 타입 지정 (FieldSetMapper 자동 생성)
                .build();
    }
}

TXT 파일 읽기(고정 길이 방식 – Fixed-Length)

각 데이터 필드가 고정된 바이트(byte) 또는 글자 수를 차지하는 오래된 시스템 연동 파일에서 사용합니다.

샘플 파일

김철수       30   chulsu@example.com       
이영희       28   younghee@test.com        
박지훈       35   jihoon@company.com

스프링 배치 코드

  • .columns(new Range(…)) : 데이터의 위치(범위)를 정확히 지정 합니다. 주의 : 인덱스는 0이 아닌 1부터 시작 합니다.
  • 자동 Trim (공백 제거) 고정 길이 파일은 빈 공간이 공백(스페이스)으로 채워져 있습니다. FlatFileItemReaderBuilder를 사용하면 매핑 과정에서 좌우공백을 자동으로 제거해 줍니다.
import org.springframework.batch.item.file.FlatFileItemReader;
import org.springframework.batch.item.file.builder.FlatFileItemReaderBuilder;
import org.springframework.batch.item.file.transform.Range;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ClassPathResource;

@Configuration
public class FixedLengthReaderConfig {

    @Bean
    public FlatFileItemReader<Person> fixedLengthItemReader() {
        return new FlatFileItemReaderBuilder<Person>()
                .name("fixedLengthItemReader")
                .resource(new ClassPathResource("input.txt"))
                .fixedLength() // 고정 길이 방식 사용 선언
                .columns(
                        new Range(1, 10),  // 1~10번째 글자: 이름
                        new Range(11, 15), // 11~15번째 글자: 나이
                        new Range(16, 40)  // 16~40번째 글자: 이메일
                )
                .names("name", "age", "email") // 컬럼 범위에 순서대로 이름 부여
                .targetType(Person.class) // Person 객체로 매핑 (자동 Trim 적용됨)
                .build();
    }
}

관련 글 보기