getResourceAsStream returns null

2018-12-31 07:53发布

I'm loading a text file from within a package in a compiled JAR of my Java project. The relevant directory structure is as follows:

/src/initialization/Lifepaths.txt

The code being used to load the file is:

public class Lifepaths {
    public static void execute() {
        System.out.println(Lifepaths.class.getClass().
            getResourceAsStream("/initialization/Lifepaths.txt"));
    }

    private Lifepaths() {}

    //This is temporary; will eventually be called from outside
    public static void main(String[] args) {execute();}
}

The print out will always print null, no matter what I use. I'm not sure why the above wouldn't work, so I've also tried:

  • "/src/initialization/Lifepaths.txt"
  • "initialization/Lifepaths.txt"
  • "Lifepaths.txt"

Neither of these work. I've read numerous questions so far on the topic, but none of them have been helpful - usually, they just say to load files using the root path, which I'm already doing. That, or just load the file from the current directory (just load filename), which I've also tried. The file is being compiled into the JAR in the appropriate location with the appropriate name.

How do I solve this?

12条回答
谁念西风独自凉
2楼-- · 2018-12-31 08:32

You might want to try this to get the stream i.e first get the url and then open it as stream.

URL url = getClass().getResource("/initialization/Lifepaths.txt"); 
InputStream strm = url.openStream(); 

I once had a similar question: Reading txt file from jar fails but reading image works

查看更多
骚的不知所云
3楼-- · 2018-12-31 08:33

I found myself in a similar issue. Since I am using maven I needed to update my pom.xml to include something like this:

   ...
</dependencies>
<build>
    <resources>
        <resource>
            <directory>/src/main/resources</directory>
        </resource>
        <resource>
            <directory>../src/main/resources</directory>
        </resource>
    </resources>
    <pluginManagement>
        ...

Note the resource tag in there to specify where that folder is. If you have nested projects (like I do) then you might want to get resources from other areas instead of just in the module you are working in. This helps reduce keeping the same file in each repo if you are using similar config data

查看更多
几人难应
4楼-- · 2018-12-31 08:34

Don't use absolute paths, make them relative to the 'resources' directory in your project. Quick and dirty code that displays the contents of MyTest.txt from the directory 'resources'.

@Test
public void testDefaultResource() {
    // can we see default resources
    BufferedInputStream result = (BufferedInputStream) 
         Config.class.getClassLoader().getResourceAsStream("MyTest.txt");
    byte [] b = new byte[256];
    int val = 0;
    String txt = null;
    do {
        try {
            val = result.read(b);
            if (val > 0) {
                txt += new String(b, 0, val);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } 
    } while (val > -1);
    System.out.println(txt);
}
查看更多
时光乱了年华
5楼-- · 2018-12-31 08:35

What worked for me was to add the file under My Project/Java Resources/src and then use

this.getClass().getClassLoader().getResourceAsStream(myfile.txt);

I didn't need to explicity add this file to the path (adding it to /src does that apparently)

查看更多
姐姐魅力值爆表
6楼-- · 2018-12-31 08:40

So there are several ways to get a resource from a jar and each has slightly different syntax where the path needs to be specified differently.

The best explanation I have seen is this article from JavaWorld. I'll summarize here, but if you want to know more you should check out the article.

Methods

1) ClassLoader.getResourceAsStream().

Format: "/"-separated names; no leading "/" (all names are absolute).

Example: this.getClass().getClassLoader().getResourceAsStream("some/pkg/resource.properties");

2) Class.getResourceAsStream()

Format: "/"-separated names; leading "/" indicates absolute names; all other names are relative to the class's package

Example: this.getClass().getResourceAsStream("/some/pkg/resource.properties");

查看更多
只靠听说
7楼-- · 2018-12-31 08:46

There seems to be issue with the ClassLoader that you are using. Use the contextClassLoader to load class. This is irrespective of whether it is in a static/non-static method

Thread.currentThread().getContextClassLoader().getResourceAsStream......

查看更多
登录 后发表回答