18

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!

Greg
  • 411
  • 2
  • 6
  • 15

7 Answers7

35

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/

M. Deinum
  • 115,695
  • 22
  • 220
  • 224
Seamas
  • 1,041
  • 7
  • 13
11

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();

Liping Huang
  • 4,378
  • 4
  • 29
  • 46
  • 1
    Did not work for me, perhaps bcs I'm using Spring Boot? – Greg Jan 20 '17 at 02:18
  • @Greg Yes, I'm using spring boot 1.4.3, what's the exact verion for you? – Liping Huang Jan 20 '17 at 02:19
  • mine is 1.4.3.RELEASE, this is strange ! – Greg Jan 20 '17 at 02:21
  • 1
    @Greg is this a clean spring boot project? did you change your spring boot profiles? and maybe you need to check your `Spring-Boot-Classes` in MANIFEST.MF file, like `Spring-Boot-Classes: BOOT-INF/classes/` – Liping Huang Jan 20 '17 at 02:25
  • Yes, It's a brand new one and all are default configurations – Greg Jan 20 '17 at 02:27
  • @Greg interestiong, maybe you can push it to github, so I can get your codes and have a try. – Liping Huang Jan 20 '17 at 02:28
  • it's a simple one, one controller and one service class – Greg Jan 20 '17 at 02:30
  • @Greg OK, the real problem is caused by `try(Scanner sc = new Scanner(new FileInputStream(resource.getFile())))`, actually `resourceLoader.getResource("classpath:static/Sample.txt")` get the real resoruce. – Liping Huang Jan 20 '17 at 02:53
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/133599/discussion-between-liping-huang-and-greg). – Liping Huang Jan 20 '17 at 02:57
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

BERGUIGA Mohamed Amine
  • 6,094
  • 3
  • 40
  • 38
3

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()
Mohammed Rafeeq
  • 2,586
  • 25
  • 26
1

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();
}
Hasitha Jayawardana
  • 2,326
  • 4
  • 18
  • 36
0

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;
    }
}
Marosdee Uma
  • 719
  • 10
  • 14
0

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

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

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

Ritu Gupta
  • 2,249
  • 1
  • 18
  • 11