当前位置: 首页 > 知识库问答 >
问题:

Spring批处理文件处理错误,我的ItemReader未关闭

闻人飞翼
2023-03-14

我尝试了另一个解决方案,使用自定义的FlatItemReader,我重写了close()方法,在关闭后删除文件。这个解决方案发生了一个奇怪的事情,我的close方法被调用了两次,有些时候我可以删除文件,有些时候我不能删除它...

请参阅下面的日志:

o.s.b.c.l.support.SimpleJobLauncher      : Job: [SimpleJob: [name=job]] launched with the following parameters: [{time=1551704019790, PATH_TO_FILE=C:\tmp\tmpCorresp\ESPCORR_LITE2.CSV, organisationId=153}]
o.s.batch.core.job.SimpleStepHandler     : Executing step: [step1]
c.m.b.a.config.BatchConfig               : Do Close Started !!!!
c.m.b.a.config.BatchConfig               : start Deletion
c.m.b.a.config.BatchConfig               : File is not deleted
c.m.b.a.config.BatchConfig               : Do Close Started !!!!
c.m.b.a.config.BatchConfig               : start Deletion
c.m.b.a.config.BatchConfig               : File is not deleted
o.s.b.c.l.support.SimpleJobLauncher      : Job: [SimpleJob: [name=job]] completed with the following parameters: [{time=1551704019790, PATH_TO_FILE=C:\tmp\tmpCorresp\ESPCORR_LITE2.CSV, organisationId=153}] and the following status: [COMPLETED]
c.m.b.a.scheduled.TestTask               : FTP FILES FOR organisation2 DOWNLOADED
c.m.b.a.scheduled.TestTask               : Et BIM le flux !

我的close方法的代码:

@Override
        public void close() throws ItemStreamException {
            super.close();
            deleteFileAfterClose();
        }

        private void deleteFileAfterClose(){
            log.debug("start Deletion");
            File f = null;
            try {
                f = resourceHandler.getFile();
            } catch (IOException e) {
                log.error("Error while retrieving file : ", e);
            }
            if(f != null && f.exists()){
                boolean delete = f.delete();
                if(delete){
                    log.debug("File is deleted");
                }
                else {
                    log.debug("File is not deleted");
                }
            }
        }

我的BatchConfig.java:

@Configuration
@PropertySource("classpath:config/default.properties")
@EnableBatchProcessing
public class BatchConfig {

    private static final Logger log = LoggerFactory.getLogger(BatchConfig.class);

    @Autowired
    public JobBuilderFactory jobBuilderFactory;

    @Autowired
    public StepBuilderFactory stepBuilderFactory;

    @Autowired
    public CorrespondentDao correspondentDao;

    @Autowired
    public JobRepository jobRepository;

    @Bean
    public SimpleJobLauncher simpleJobLauncher() throws Exception {
        SimpleJobLauncher simpleJobLauncher = new SimpleJobLauncher();
        simpleJobLauncher.setJobRepository(jobRepository);
        simpleJobLauncher.setTaskExecutor(new SyncTaskExecutor());
        simpleJobLauncher.afterPropertiesSet();
        return simpleJobLauncher;
    }

    @Bean
    public Job job(Step step1, Step step2) {
        return jobBuilderFactory.get("job")
                .preventRestart()
                .start(step1)
                .next(step2)
                .build();
    }

    @Bean
    Step step1(FlatFileItemReader<CorrespondentEntity> reader, ItemWriter<CorrespondentEntity> writer) {
        return stepBuilderFactory
                .get("step1")
                .<CorrespondentEntity, CorrespondentEntity>chunk(1)
                .reader(reader)
                .processor(new Processor())
                .writer(writer)
                .build();
    }

    //step for deleting the file
    @Bean
    Step step2(FileDeletingTasklet deletingTask) {
        FileDeletingTasklet task = deletingTask;
        return stepBuilderFactory.get("step2")
                .allowStartIfComplete(true)
                .tasklet(task)
                .build();
    }

    @SuppressWarnings("Duplicates")
    @Bean
    @JobScope
    public FlatFileItemReader<CorrespondentEntity> reader(@Value("#{jobParameters['PATH_TO_FILE']}") String pathToFile ) throws MalformedURLException {
        FlatFileItemReader<CorrespondentEntity> reader = new CustomReader<>();

        reader.setResource(new FileUrlResource(pathToFile));
        reader.setLinesToSkip(1);
        reader.setLineMapper(new csvLineMapper());
        return reader;
    }

    @Bean
    @JobScope
    public ItemWriter<CorrespondentEntity> writer(CorrespondentDao correspondentDao, @Value("#{jobParameters['organisationId']}") Long organisationId){
        return new Writer(correspondentDao, organisationId);
    }

    @Bean
    @JobScope
    public FileDeletingTasklet deletingTask(@Value("#{jobParameters['PATH_TO_FILE']}") String pathToFile){
        return new FileDeletingTasklet(pathToFile);
    }

    private class CustomReader<T> extends FlatFileItemReader<T> implements ItemStream {

        private Resource resourceHandler;

        @Override
        public void setResource(Resource resource) {
            super.setResource(resource);
            this.resourceHandler = resource;
        }

        @Override
        public void close() throws ItemStreamException {
            super.close();
        }

        //Not used for the moment
        private void deleteFileAfterClose(){
            log.debug("start Deletion");
            File f = null;
            try {
                f = resourceHandler.getFile();
            } catch (IOException e) {
                log.error("Error while retrieving file : ", e);
            }
            if(f != null && f.exists()){
                boolean delete = f.delete();
                if(delete){
                    log.debug("File is deleted");
                }
                else {
                    log.debug("File is not deleted");
                }
            }
        }
    }
}

filedeletingTasklet.java

import com.micropole.biomnis.authentification.scheduled.TestTask;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.batch.core.StepContribution;
import org.springframework.batch.core.scope.context.ChunkContext;
import org.springframework.batch.core.step.tasklet.Tasklet;
import org.springframework.batch.repeat.RepeatStatus;

import java.io.File;

public class FileDeletingTasklet implements Tasklet {


    private static final Logger log = LoggerFactory.getLogger(TestTask.class);
    private String filePath;

    public FileDeletingTasklet(String filePath) {
        this.filePath = filePath;
    }

    public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) throws Exception {
        log.debug("try to delete this file : " + filePath);
        File f = new File(filePath);
        if(f.exists()){
            boolean delete = f.delete();
            if(delete){
                log.debug("File is deleted !!!!");
                return RepeatStatus.FINISHED;
            }
            else {
                log.debug("File is not deleted !!!");
                return RepeatStatus.FINISHED;
            }
        }
        return RepeatStatus.FINISHED;
    }

}

共有1个答案

田翰林
2023-03-14

另一个实现目标的方法是创建一个三步工作:

  1. 将文件下载到本地
  2. 进程文件
  3. 删除文件

每一步都执行一个特定的操作,并可能帮助您以更好的方式管理流异常。

 类似资料:
  • 我正在尝试创建一个应用程序,该应用程序使用spring-batch-excel扩展名来读取用户通过web界面上传的Excel文件,以便解析Excel文件中的地址。 当代码运行时,没有错误,但我得到的只是我日志中的以下内容。即使我的处理器和Writer中都有log/syso(它们从未被调用过,我所能想象的是它没有正确读取文件,也没有返回要处理/写入的数据)。是的,这个文件有数据,实际上有几千条记录。

  • 我开始学习spring batch,遇到一个问题,当我想使用在数据库中持久化作业的状态时。编译器显示: “原因:org.springframework.beans.factory.beanCreationException:创建类路径资源[springconfig.xml]中定义的名为'job repository'的bean时出错:调用init方法失败;嵌套异常为java.lang.noClas

  • 在happy path场景中,我有一个spring批处理工作,但现在我将重点放在错误处理上。 但是,在另一个测试中,我想证明一个不可预见的数据库错误会导致作业失败。为此,我创建了一个触发器,该触发器会导致对要插入的表的插入失败。 这似乎起作用了,在writer执行之后,在事务提交期间抛出异常,并且我得到以下日志消息: 这似乎也是预期的行为。问题是,这并不能阻止工作。该步骤退出到SimplyRetr

  • 我有这个批处理文件来将所有文件从一个目录复制到另一个目录。源目录和目标目录写入文本文件。所以我有这个: 批处理文件 这是一个copy\u list\u测试。txt文件 因此,当我尝试运行脚本时,他在“C:\Users\mcastrio\Desktop\C”上创建了一个新文件夹,而不是将文件放在C:\temp\MESSERVER中 我的错误在哪里? 我们能帮我吗?最佳规范

  • 需要读取spring批处理中的文件,对其进行处理并将其作为一个提要保存。一个提要包含50%的信息。当我必须持久化提要的最终结果时,我需要使用公共字段将它们组合起来,并像一个项目一样持久化。请参见下面的示例。 我需要保留的最终信息如下: 请建议我如何在我的Spring批工作中实现这一点。 谢谢