10

I use Spring Batch for parse csv file. It works great, when file in resource directory, but doesn't work from another place. I get suck error

Caused by: java.lang.IllegalStateException: Input resource must exist (reader is in 'strict' mode): class path resource [c:/data/geodata1.csv]

My code

spring.datasource:
    driverClassName: org.h2.Driver
    url: jdbc:h2:mem:mydb;MODE=Oracle
server:
  port: 9001
geodata:
  file: c:/data/geodata1.csv

@Value("${geodata.file}")
private String filePath;

@Bean
public FlatFileItemReader<Person> reader() {
    FlatFileItemReader<Person> reader = new FlatFileItemReader<Person>();
    reader.setResource(new ClassPathResource(filePath));
    reader.setLineMapper(new DefaultLineMapper<Person>() {{
        setLineTokenizer(new DelimitedLineTokenizer() {{
            setNames(new String[] {"clientId", "longitude", "latitude", });
        }});
        setFieldSetMapper(new BeanWrapperFieldSetMapper<Person>() {{
            setTargetType(Person.class);
        }});
    }});
    return reader;
}

But this code works good

File file = new File(filePath);
jeb
  • 78,592
  • 17
  • 171
  • 225
ttt
  • 401
  • 2
  • 4
  • 17

4 Answers4

9

use PathResource from org.springframework.core.io , it worked for me

@Bean
@StepScope
public FlatFileItemReader<CourseCountry> reader(@Value("#{jobParameters[fullPathFileName]}") String pathToFile) {
    return new FlatFileItemReaderBuilder<CourseCountry>()
      .name("studentItemReader")        
      .resource(new PathResource(pathToFile))
      .lineMapper(lineMapper())
      .linesToSkip(1)
      .build();
}
Elsayed
  • 2,712
  • 7
  • 28
  • 41
4

Just found the solution use org.springframework.core.io.UrlResource; class instead of org.springframework.core.io.ClassPathResource;

ttt
  • 401
  • 2
  • 4
  • 17
4

I had find the same problem and i'd use org.springframework.core.io.FileSystemResource class like this: file: c:\data\geodata1.csv reader.setResource(new FileSystemResource(file));

zedtimi
  • 306
  • 1
  • 6
0

Solution 1 : You can use PathResource as follows

@Bean
public FlatFileItemReader<Person> reader() {
   new FlatFileItemReaderBuilder<Person>()
                .name("JobName")
                .resource(new PathResource(getReceivedFilePath("Location")))
                .targetType("Targetclass".class)
                .linesToSkip(" count of no of lines to skip")
                .delimited()
                .delimiter(recordSeparator)
                .includedFields(new Integer[] { 0, 1})
                .names(new String[] { "param1 in target class","param2 in target class etc" })
                .build();
}

The getReceivedFilePath that u pass to PathResource should be as follows, which takes any file that starts with or ends with etc.

 public String getReceivedFilePath(String fileName) {

        File directory = new File(file.location);
        if (directory.isDirectory()) {
            File[] files = directory.listFiles((dir, name) -> name.toLowerCase().endsWith("extension.type"));
            for (File file : files) {
                if (FilenameUtils.getBaseName(file.getName()).startsWith(FilenameUtils.getBaseName(fileName))) {
                    return file.getAbsolutePath();
                }
            }
        }
        return directory.getName();
    }

Solution 2 : You can use PathResource, but your filename should match the exact path that you supply

Ex: new PathResource("C:\files\filename.csv")

Ramya Musunuru
  • 177
  • 1
  • 5