读取BufferedReader的内容时出现NullPointerException,尽管它不是空的

时间:2016-07-01 12:52:23

标签: java jar nullpointerexception bufferedreader getresource

每当我尝试获取BufferedReader的内容时,每次运行已经打包在jar中的项目时,我都会收到NullPointerException。当它在IDE(IntelliJ)内部运行时,没有任何问题。我已经检查过所有以前的InputStream,它们似乎没问题。你可能有点tipp吗?提前谢谢!

String pathToFontDir = "/fonts/Open_Sans";
GraphicsEnvironment localGE = GraphicsEnvironment.getLocalGraphicsEnvironment();
final InputStream is = Session.class.getResourceAsStream(pathToFontDir);
if(is != null){

        final InputStreamReader isr = new InputStreamReader(is, StandardCharsets.UTF_8);
        final BufferedReader br = new BufferedReader(isr);

        List fonts = br.lines().collect(Collectors.toList()); //throws NullPointerException
        if(fonts.size() > 0){
            for(Object font: fonts){
                InputStream fis = loader.getResourceAsStream(pathToFontDir + "/" + font);
                localGE.registerFont(Font.createFont(Font.TRUETYPE_FONT, fis));
            }
        } else{
            throw new IOException("Der angegebene Ordner enthält keine Schriftdateien!");
        }
    }

我也试过检查一下,我的BufferedReader包含任何东西,但它再次抛出异常而没有返回任何一行:

        String fontName;
        while((fontName = br.readLine()) != null) //throws NPE as well
            System.out.println(fontName);

堆栈跟踪:

  

显示java.lang.NullPointerException       at java.io.FilterInputStream.read(Unknown Source)       at sun.nio.cs.StreamDecoder.readBytes(Unknown Source)       at sun.nio.cs.StreamDecoder.implRead(Unknown Source)       at sun.nio.cs.StreamDecoder.read(Unknown Source)       在java.io.InputStreamReader.read(未知来源)       在java.io.BufferedReader.fill(未知来源)       在java.io.BufferedReader.readLine(未知来源)       在java.io.BufferedReader.readLine(未知来源)       在java.io.BufferedReader $ 1.hasNext(未知来源)       at java.util.Iterator.forEachRemaining(Unknown Source)       at java.util.Spliterators $ IteratorSpliterator.forEachRemaining(Unknown Source)       at java.util.stream.AbstractPipeline.copyInto(Unknown Source)       at java.util.stream.AbstractPipeline.wrapAndCopyInto(Unknown Source)       at java.util.stream.ReduceOps $ ReduceOp.evaluateSequential(Unknown Source)       at java.util.stream.AbstractPipeline.evaluate(Unknown Source)       在java.util.stream.ReferencePipeline.collect(未知来源)       在main.java.backend.Session.importFontResource(Session.java:137)       在main.java.backend.Session.main(Session.java:180)

3 个答案:

答案 0 :(得分:2)

您为资源/fonts/Open_Sans打开一个InputStream。

在IDE中运行时,资源是目录。似乎 - 我不知道 - 它返回该目录中所有文件的列表。

当您运行打包在jar中的代码时,资源指向Jar文件中的目录条目。该资源的InputStream不为null,但是当您开始从中读取时,会抛出NPE:

Exception in thread "main" java.lang.NullPointerException
    at java.io.FilterInputStream.read(FilterInputStream.java:133)
    at sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:284)
    at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:326)
    at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:178)
    at java.io.InputStreamReader.read(InputStreamReader.java:184)
    at java.io.BufferedReader.fill(BufferedReader.java:161)
    at java.io.BufferedReader.readLine(BufferedReader.java:324)
    at java.io.BufferedReader.readLine(BufferedReader.java:389)

(您从getResourceAsStream获得的输入流是sun.net.www.protocol.jar.JarURLConnection$JarURLInputStream,它扩展了FilterInputStream并且它不会清理其构造函数参数,后者会导致NPE。)

答案 1 :(得分:2)

您无法读取资源目录。由于标准java中没有 easy 规定,因此请创建一个"目录"在资源文件中列出,并阅读。 保持传统。

对于"不安"解决方案:http://www.uofr.net/~greg/java/get-resource-listing.html

答案 2 :(得分:0)

您可能需要考虑以其他方式打开流。当我想要一个JAR或类路径从它自己读取时,我使用这个链:

File classpathBase = new File(this.getClass().getProtectionDomain().getCodeSource().getLocation().toURI());

一旦你拥有了它,它就是一个Jar文件或一个目录。从那里,你可以使用一些方法来阅读资源:

String resourceName = "/fonts/Open_Sans";
InputStream in;
JarFile jarFile = null;
if (classpathBase.isDirectory()){
   in = new FileInputStream(classPathBase.getPath() + resourceName);
} else {
   jarFile = new JarFile(file);
   JarEntry entry = jarFile.getEntry(resourceName);
   in = jarFile.getInputStream(entry);
}
// read from in.read()
in.close();
if (jarFile != null){
    jarFile.close();
}