使用Spring Batch实现Txt转Csv的ItemReader代码咨询
Spring Batch 读取TXT文件ItemReader 修正方案
你当前的Reader代码框架逻辑是正确的,只需要补充TXT文件的专属适配配置即可正常使用,调整点如下:
- 指定分隔符:
DelimitedLineTokenizer默认使用逗号作为分隔符,需根据你的TXT文件实际字段分隔规则显式配置:如果是制表符分隔用DelimitedLineTokenizer.DELIMITER_TAB,如果是竖线/空格等自定义分隔符直接传入对应字符串即可。 - 配置文件编码:FlatFileItemReader默认使用UTF-8编码,若你的TXT是Windows下生成的GBK/GB2312编码,需显式指定编码避免乱码。
- 添加配置类注解:
RecordsReader类需要加@Configuration注解,否则Spring无法识别你注册的Reader Bean。 - 自定义类型转换(可选):如果
Records实体类包含日期、数字等非String类型字段,需补充自定义转换规则避免映射失败。
以下是修正后的完整代码:
import org.springframework.batch.item.file.FlatFileItemReader; import org.springframework.batch.item.file.mapping.BeanWrapperFieldSetMapper; import org.springframework.batch.item.file.mapping.DefaultLineMapper; import org.springframework.batch.item.file.transform.DelimitedLineTokenizer; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.io.FileSystemResource; // 必须加Configuration注解 @Configuration public class RecordsReader { @Bean public FlatFileItemReader<Records> reader() { FlatFileItemReader<Records> reader = new FlatFileItemReader<>(); reader.setResource(new FileSystemResource("C://output/pip-1.7.txt")); // 配置文件编码,根据实际情况调整 reader.setEncoding("GBK"); reader.setLineMapper(getLineMapper()); // 如果TXT文件没有表头,删除这行避免丢失第一行数据 reader.setLinesToSkip(1); return reader; } private DefaultLineMapper<Records> getLineMapper() { DefaultLineMapper<Records> lineMapper = new DefaultLineMapper<>(); DelimitedLineTokenizer lineTokenizer = new DelimitedLineTokenizer(); // 配置分隔符,示例为制表符,根据实际情况替换为你的分隔符 lineTokenizer.setDelimiter(DelimitedLineTokenizer.DELIMITER_TAB); // 确保字段名顺序和TXT每行的字段顺序完全一致 lineTokenizer.setNames(Records.fields()); BeanWrapperFieldSetMapper<Records> fieldSetter = new BeanWrapperFieldSetMapper<>(); fieldSetter.setTargetType(Records.class); // 若有自定义类型转换需求可以在这里配置ConversionService,不需要就删掉下面这段 // DefaultConversionService conversionService = new DefaultConversionService(); // conversionService.addConverter(new StringToLocalDateConverter("yyyy-MM-dd")); // fieldSetter.setConversionService(conversionService); lineMapper.setLineTokenizer(lineTokenizer); lineMapper.setFieldSetMapper(fieldSetter); return lineMapper; } }
上线前校验点
- 确认
Records类提供无参构造函数和所有字段对应的setter方法,否则BeanWrapper映射会报错 - 确认
Records.fields()返回的字段名顺序,和TXT文件每行的字段顺序完全一致,顺序错位会导致字段值匹配错误 - 测试阶段可以先把
setLinesToSkip设置为0,确认第一条数据是否正确映射,再调整跳行规则
内容的提问来源于stack exchange,提问作者aditya kamath
相关产品推荐
相关产品推荐

