每当我尝试获取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)
答案 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();
}