首页 文章

getResourceAsStream()仅在jar文件中返回null

提问于
浏览
6

我知道同样的问题被问过很多次,但是经过所有已经发布的答案,我找不到解决方案 .

首先,这是我在项目中遇到它后用来测试问题的代码:

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文件内容如下:
http://i.stack.imgur.com/1y8i8.png

netbeans项目文件夹中的src文件夹如下:
http://i.stack.imgur.com/AXj7s.png

所以我现在真的很困惑,我在使用netbeans构建时尝试使用默认设置,但我对这个问题感到很失望 .

任何提示或想法将不胜感激!

3 回答

  • 0

    我认为getResourceAsStream不是从文件系统读取的,前导斜杠将尝试从类路径的根读取(如果添加目录将从根读取) . 如果你没有放置前导斜杠,你将从类来自的包中读取 .

    您是否在类路径中添加了要从中读取文件的目录/子目录?

  • 0

    TL; DR这是由于NTFS权限的一些愚蠢问题,移动jar使其工作

    所以我现在觉得很蠢......

    我尝试在Linux环境中运行它,一切都按照假设运行 . 这些调用中的每一个都返回一个指向资源的非null InputStream .

    所以我做了一些非常简单的事情:只是在Windows中编译的jar中移动以检查它是否与NTFS权限有关(请记住我使用的是管理员帐户,我可以在这些文件夹中自由编写,读取和执行) . 将它移动到项目的根目录不起作用,但在桌面上移动它 .

    令我感到惊讶的是,在我正在做的项目的其他部分

    URL jarUrl = PairsDeck.class.getProtectionDomain().getCodeSource().getLocation();
    

    读取jar文件的整个内容,即使在旧目录中也是如此,所以这就是为什么我从一开始就没有想过搞过权限(我从具有管理员权限的命令提示符启动它) .

    所以我想不管怎样,程序可以通过该调用读取它的jar,但是由于NTFS权限的一些问题,不能从我的netbeans项目文件夹中加载它 .

    增加一些困惑

    File file = new File(jarUrl.toURI());
    file.canWrite();
    file.canRead();
    file.canExecute();
    

    以上所有都是真的 .

    我只是想知道是否有办法更好地理解这个问题,并且可能有办法从java代码中发出一些权限错误信号 .

    衷心感谢所有参与帮助的人!

  • -1

    这里有两个问题 .

    • Windows不区分大小写 . 其他平台和jar名称内部区分大小写 .

    • getClass() 类确定资源在哪个jar / class路径中 . 特别是单元测试不会放在 jar 里,或者子类可能位于 jar 外面 . 使用 SomeClassInJar.class 或使用ClassLoader搜索所有jar /类路径 . 类加载器仅使用绝对路径,并且不能使用 / 启动路径 .

相关问题