Cannot read file within jar file

2019-09-17 00:40发布

问题:

I developped an application using spring-boot, I need to read a csv file that contain emails.

this is a snippet how I do:

public Set<String> readFile() {
        Set<String> setOfEmails = new HashSet<String>();

        try {
            ClassPathResource cl = new ClassPathResource("myFile.csv");
            File file = cl.getFile();
            Stream<String> stream = Files.lines(Paths.get(file.getPath()));
            setOfEmails = stream.collect(Collectors.toSet());

        } catch (IOException e) {
            logger.error("file error " + e.getMessage());
        }
        return setOfEmails;
    } 

It works when I execute the application using eclipse: run As --> spring-boot app

But when I put the jar into a container docker the method readFile() return an empty set.

I use gradle for build the application

Would you have any ideas ?

Best regards

回答1:

The javadoc for ClassPathResource states:

Supports resolution as java.io.File if the class path resource resides in the file system, but not for resources in a JAR. Always supports resolution as URL.

So when the resource (the CSV file) is in a JAR file, getFile() is going to fail.

The solution is to use getURL() instead, then open the URL as an input stream, etcetera. Something like this:

public Set<String> readFile() {
    Set<String> setOfEmails = new HashSet<String>();

    ClassPathResource cl = new ClassPathResource("myFile.csv");
    URL url = cl.getURL();
    try (BufferedReader br = new BufferedReader(
                             new InputStreamReader(url.openStream()))) {

        Stream<String> stream = br.lines();
        setOfEmails = stream.collect(Collectors.toSet());
    } catch (IOException e) {
        logger.error("file error " + e.getMessage());
    }
    return setOfEmails;
} 

If it still fails check that you are using the correct resource path.



回答2:

I do not work with Spring, but I found the Javadoc of ClassPathResource that states:

Supports resolution as java.io.File if the class path resource resides in the file system, but not for resources in a JAR. Always supports resolution as URL.

try with getURL() instead of getFile().



回答3:

Use http://jd.benow.ca/ Jd GUI drop your jar file there and

1) check is the file is there in the jar

2) If Yes then see the path/folder structure where it is placed.

3) If Yes folder exists Access the File using "/<path>/myFile.csv"

Cheers Enjoy coding