我知道同样的问题被问过很多次,但是经过所有已经发布的答案,我找不到解决方案 .
首先,这是我在项目中遇到它后用来测试问题的代码:
InputStream test;
System.out.println(this.getClass());
System.out.println(("classpath is: " + System.getProperty("java.class.path")));
test = getClass().getResourceAsStream("/pairs/images/100/back/back1.png");
if (test == null)
{
System.out.println("getClass().getResourceAsStream(\"/pairs/images/100/back/back1.png\") is null");
test = GridPanel.class.getClassLoader().getResourceAsStream("pairs/images/100/back/back1.png");
}
if (test == null)
{
System.out.println("GridPanel.class.getClassLoader().getResourceAsStream(\"pairs/images/100/back/back1.png\") is null");
test = ClassLoader.getSystemClassLoader().getResourceAsStream("pairs/images/100/back/back1.png");
}
if (test == null)
{
System.out.println("ClassLoader.getSystemClassLoader().getResourceAsStream(\"pairs/images/100/back/back1.png\") is null");
Thread.currentThread().getContextClassLoader().getResourceAsStream("pairs/images/100/back/back1.png");
}
if (test == null)
System.out.println("Thread.currentThread().getContextClassLoader().getResourceAsStream(\"pairs/images/100/back/back1.png\") is null");
因此,根据 Headers ,这些对getResourceAsStream()的调用都会返回null,但只有在执行jar文件时,当在IDE(Netbeans 8.0.2)内启动时,它们都返回正确的流(单独测试不使用这段代码)我可以用它 .
jar文件内容如下:
netbeans项目文件夹中的src文件夹如下:
所以我现在真的很困惑,我在使用netbeans构建时尝试使用默认设置,但我对这个问题感到很失望 .
任何提示或想法将不胜感激!
3 回答
我认为getResourceAsStream不是从文件系统读取的,前导斜杠将尝试从类路径的根读取(如果添加目录将从根读取) . 如果你没有放置前导斜杠,你将从类来自的包中读取 .
您是否在类路径中添加了要从中读取文件的目录/子目录?
TL; DR这是由于NTFS权限的一些愚蠢问题,移动jar使其工作
所以我现在觉得很蠢......
我尝试在Linux环境中运行它,一切都按照假设运行 . 这些调用中的每一个都返回一个指向资源的非null InputStream .
所以我做了一些非常简单的事情:只是在Windows中编译的jar中移动以检查它是否与NTFS权限有关(请记住我使用的是管理员帐户,我可以在这些文件夹中自由编写,读取和执行) . 将它移动到项目的根目录不起作用,但在桌面上移动它 .
令我感到惊讶的是,在我正在做的项目的其他部分
读取jar文件的整个内容,即使在旧目录中也是如此,所以这就是为什么我从一开始就没有想过搞过权限(我从具有管理员权限的命令提示符启动它) .
所以我想不管怎样,程序可以通过该调用读取它的jar,但是由于NTFS权限的一些问题,不能从我的netbeans项目文件夹中加载它 .
增加一些困惑
以上所有都是真的 .
我只是想知道是否有办法更好地理解这个问题,并且可能有办法从java代码中发出一些权限错误信号 .
衷心感谢所有参与帮助的人!
这里有两个问题 .
Windows不区分大小写 . 其他平台和jar名称内部区分大小写 .
getClass()
类确定资源在哪个jar / class路径中 . 特别是单元测试不会放在 jar 里,或者子类可能位于 jar 外面 . 使用SomeClassInJar.class
或使用ClassLoader搜索所有jar /类路径 . 类加载器仅使用绝对路径,并且不能使用/
启动路径 .