'Spring Boot - Reading Text File using ResourceLoader

I’m trying to read a text file using Spring resource loader like this :

Resource resource  = resourceLoader.getResource("classpath:\\static\\Sample.txt");

The file locates here in my Spring boot project: enter image description here

It works fine when running the application in eclipse, but when I package the application then run it using java –jar , I get file not found exception :

java.io.FileNotFoundException: class path resource [static/Sample.txt] cannot be resolved to absolute file path because it does not reside in the
 file system: jar:file:/C:/workspace-test/XXX/target/XXX-0.0.1-SNAPSHOT.jar!/BOOT-INF/classes!/static/Sample.txt

I unziped the Jar file the Sample locates in : XXX-0.0.1-SNAPSHOT\BOOT-INF\classes\static\Sample.txt

Can someone help me please ?

Thanks in advance!



Solution 1:[1]

I have checked your code.If you would like to load a file from classpath in a Spring Boot JAR, then you have to use the resource.getInputStream() rather than resource.getFile().If you try to use resource.getFile() you will receive an error, because Spring tries to access a file system path, but it can not access a path in your JAR.

detail as below:

https://smarterco.de/java-load-file-classpath-spring-boot/

Solution 2:[2]

Please try resourceLoader.getResource("classpath:static/Sample.txt");

Working with this code when run with java -jar XXXX.jar

enter image description here

------ update ------

After go through your codes, the problem is you try to read the file by the FileInputStream but actually it's inside the jar file.

But actually you get the org.springframework.core.io.Resource so means you cat get the InputStream, so you can do it like new BufferedReader(new InputStreamReader(resource.getInputStream())).readLine();

Solution 3:[3]

I had the same problem and as @Gipple Lake explained, with Spring boot you need to load file as inputStream. So bellow I'll add my code as example, where I want to read import.xml file

public void init() {
    Resource resource = new ClassPathResource("imports/imports.xml");
    try {
        InputStream dbAsStream = resource.getInputStream();
        try {
            document = readXml(dbAsStream);
            } catch (SAXException e) {
                trace.error(e.getMessage(), e);
                e.printStackTrace();
            } catch (ParserConfigurationException e) {
                trace.error(e.getMessage(), e);
                e.printStackTrace();
            }
    } catch (IOException e) {
        trace.error(e.getMessage(), e);
        e.printStackTrace();
    }
    initListeImports();
    initNewImports();
}

public static Document readXml(InputStream is) throws SAXException, IOException,
      ParserConfigurationException {
      DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();

      dbf.setValidating(false);
      dbf.setIgnoringComments(false);
      dbf.setIgnoringElementContentWhitespace(true);
      dbf.setNamespaceAware(true);
      DocumentBuilder db = null;
      db = dbf.newDocumentBuilder();

      return db.parse(is);
  }

I added "imports.xml" bellow src/main/ressources/imports

Solution 4:[4]

Put the files under resources/static, it will be in classpath and read the path like below

import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;

Resource resource = new ClassPathResource("/static/pathtosomefile.txt");
resource.getURL().getPath()

Solution 5:[5]

If you want to read all file in folders

this is sample code.

import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternResolver;

@Controller
@RequestMapping("app/files")
public class FileDirController {
    @GetMapping("")
    public ModelAndView index(ModelAndView modelAndView) {

        ClassLoader cl = this.getClass().getClassLoader();
        ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver(cl);

        Resource resources[] = new Resource[0];
        try {
            resources = resolver.getResources("files/*"); // src/main/resources/files
        } catch (IOException e) {
            e.printStackTrace();
        }

        for (final Resource res : resources ) {
            System.out.println("resources" + res.getFilename());
        }


        modelAndView.setViewName("views/file_dir");

        return modelAndView;
    }
}

Solution 6:[6]

if resource is present inside resources/static/listings.csv

String path = "classpath:static/listings.csv";

ResultSet rs = new Csv().read(path, null, null);

Solution 7:[7]

Adding the answer from here. Read the ClassPathResource and copy the content to a String.

try {
   ClassPathResource classPathResource = new ClassPathResource("static/Sample.txt");
   byte[] data = FileCopyUtils.copyToByteArray(classPathResource.getInputStream());
   String content = new String(data, StandardCharsets.UTF_8);
} catch (Exception ex) {
  ex.printStackTrace();
}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 M. Deinum
Solution 2
Solution 3 BERGUIGA Mohamed Amine
Solution 4 Mohammed Rafeeq
Solution 5 Marosdee Uma
Solution 6 Ritu Gupta
Solution 7 Hasitha Jayawardana