无法在以感叹号结尾的目录中打开资源(!)

Vel*_*lth 6 java resources classpath classloader javax.imageio

每当在以感叹号结尾的目录中运行可执行jar时,getResourceAsStream -method都返回null.

对于以下示例,我有一个Eclipse项目具有以下目录结构:

src\ (Source Folder)
    main\ (Package)
        Main.java
    res\ (Source Folder)
        images\
            Logo.png
Run Code Online (Sandbox Code Playgroud)

我正在阅读Logo.png如下:

public static void main(String[] args) throws IOException {
    try (InputStream is = Main.class.getClassLoader().getResourceAsStream("images/Logo.png")) {
        Image image = ImageIO.read(is);
        System.out.println(image);
    }   
}
Run Code Online (Sandbox Code Playgroud)

请参阅2个测试用例的附件.首先,可执行jar从目录"D:\ test123!@#"启动而没有任何问题.其次,可执行jar从目录"D:\ test123!@#!!!"启动,有问题.

是否不支持以感叹号结尾的目录?代码错了吗?

提前致谢.

在以!结尾的目录中运行可执行jar时出错!

jar*_*bjo 8

可能是因为这个bug或Java bug数据库中的许多类似错误:

http://bugs.sun.com/view_bug.do?bug_id=4523159

原因是jar URL中的"!/"被解释为JAR文件名和JAR本身内的路径之间的分隔符.如果目录名以!结尾,则目录末尾的"!/"字符序列将被错误地解释.在您的情况下,您实际上是尝试使用以下URL访问资源:

罐子:文件:/// d:/ test1231 @#!/test.jar /images/Logo.png

该漏洞已经开放了将近12年,并且不太可能被修复.实际上我不知道如何在不破坏其他事情的情况下修复它.问题是设计决定使用!作为JAR文件的URL方案中具有特殊含义(分隔符)的字符:

jar:<URL for JAR file>!/<path within the JAR file>
Run Code Online (Sandbox Code Playgroud)

由于感叹号是URL中允许的字符,因此它可能出现在JAR文件本身的URL中,也可能出现在JAR文件中的路径中,这使得在某些情况下无法找到实际的"!/"分隔符.