【发布时间】:2011-08-26 17:33:55
【问题描述】:
我正在尝试使用流迭代已知目录中的类文件。最终目标是获取特定包中存在的所有类的类名,然后在运行时加载类并使用反射来获取所有静态常量的名称和值。这在我从机器上的源代码运行程序时有效,但是当我将它作为 jar 运行时,BufferedReader 会从ready() 和readLine() 中抛出一个 NPE。这是代码(为简洁起见,省略了错误处理和最佳实践):
private void printClassNamesInPackage(final String strPackage) throws Exception {
// The returned implementation of InputStream seems to be at fault
final InputStream packageStream = getClass().getClassLoader().getResourceAsStream( strPackage );
final InputStreamReader streamReader = new InputStreamReader( packageStream );
final BufferedReader reader = new BufferedReader( streamReader );
// Throws NPE from inside ready() - SEE STACKTRACE BELOW
// reader.ready()
String strLine;
// Throws NPE from inside readLine() - SEE STACKTRACE BELOW
while ( null != (strLine = reader.readLine()) ) {
System.out.println( strLine );
}
}
来自reader.ready()的堆栈跟踪:
java.lang.NullPointerException
at java.io.FilterInputStream.available(FilterInputStream.java:142)
at sun.nio.cs.StreamDecoder.inReady(StreamDecoder.java:343)
at sun.nio.cs.StreamDecoder.implReady(StreamDecoder.java:351)
at sun.nio.cs.StreamDecoder.ready(StreamDecoder.java:165)
at java.io.InputStreamReader.ready(InputStreamReader.java:178)
at java.io.BufferedReader.ready(BufferedReader.java:436)
来自reader.readLine()的堆栈跟踪:
java.lang.NullPointerException
at java.io.FilterInputStream.read(FilterInputStream.java:116)
at sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:264)
at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:306)
at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:158)
at java.io.InputStreamReader.read(InputStreamReader.java:167)
at java.io.BufferedReader.fill(BufferedReader.java:136)
at java.io.BufferedReader.readLine(BufferedReader.java:299)
at java.io.BufferedReader.readLine(BufferedReader.java:362)
单步执行会发现以下InputStream 实现:
- 来源:
java.io.ByteArrayInputStream - 来自罐子:
sun.net.www.protocol.jar.JarURLConnection$JarURLInputStream
进一步查看JarURLInputStream,我发现继承的(来自FilterInputStream)字段InputStream in 是null,这导致了生成的NPE。
不幸的是,这是我在调试器中所能达到的深度。
关于如何正确执行此操作的任何想法?我错过了什么或做错了什么?谢谢!
【问题讨论】:
-
回顾一下,您是在尝试获取文件夹而不是文件的
InputStream,对吧? -
是否可以“getClass().getClassLoader().getResourceAsStream(strPackage);”是否返回 null?
-
@BalusC:是的。最初的实现只是为
strPackage目录创建了一个new File,然后使用listFiles()来获取其中的类。我正在重构它以使用流而不是File对象,这样我们就可以支持从 jar 执行。 -
@JustinKSU:不,你可以看到我提供了
getResourceAsStream返回的运行时实现。 -
文件夹不会返回
InputStream以及所有文件或其他内容的列表。使用JarInputStream以编程方式提取 JAR。 rgagnon.com/javadetails/java-0513.html
标签: java jar stream io inputstream