当路径包含任何空格时,例如在Java ist中无法加载文件%20

时间:2019-06-29 12:16:37

标签: java junit whitespace java-io junit5

我复习了有关Java文件和路径问题的很多答案,甚至有些路径中有空格,但是没有回答我想问的问题:

在非空白目录中时,为什么以下代码起作用,否则为什么会失败?

我将问题简化为问题的基本要点,所以我希望任何人都可以向我解释问题;-)

我有一个旧的API,必须将其与某些图像的文件句柄一起使用,因此我决定通过相对路径URL方法加载图像。

我知道这在jar中不起作用,但是我还不打算从jar中加载任何图像。该解决方案足以满足我当前的需求 而且我现在不想将所有内容变成流...

但是任何执行的成功很大程度上取决于执行的目录!对我来说这很奇怪。

所以我写了一个JUnit测试,并提供了一些在测试资源目录中的文件来研究这个问题。

└───imageload    
    ├───src
    │   ├───main
    │   │   ├───java
    │   │   └───resources
    │   └───test
    │       ├───java
    │       │   └───stupid
    │       │       └───test
    │       └───resources
    │           └───testset
    └───target
        ├───generated-test-sources
        │   └───test-annotations
        └───test-classes
            ├───stupid
            │   └───test
            └───testset

这是使问题显而易见的测试代码:

package stupid.test;

[... imports omitted...]

public class SimpleTest {

    public static final File getFileByRelativePathURL(String relativePath) {
        URL url = Thread.currentThread().getContextClassLoader().getResource(relativePath);
        File file = new File(url.getPath());
        return file;
    }

    @Test
    void loadImage() {

        File theFile = SimpleTest.getFileByRelativePathURL("testset/black.jpg");
        Boolean exists = theFile.exists();

        assertTrue(exists);
    }


}

在此目录中运行测试时,一切正常:

  • D:\ Temp \ working \ imageload \

从此处运行它失败:

  • D:\ Temp \不工作\ imageload \

我仔细查看了生成的文件实例,并将目录中的空间正确地转义到了该文件对象路径:

file = D:\Temp\not%20working\imageload\target\test-classes\testset\black.jpg

但是%20一定存在问题,因为根据文件类的“ exists()”方法无法找到该文件。

我希望这个问题对于您中的许多人来说可能是显而易见的,尽管我仍然希望“ theFile.exists()”在任何带有或不带有空格的目录中都返回true。

我在做什么错了?

更新:有人问我问题是否与本文重复:

不幸的是,该解决方案无法满足我寻找正确相对路径的需求。而是将绝对路径传递到文件构造函数。

但是结合JB Nizet的评论帮助我理解了这个问题...虽然这是一个非常肮脏的解决方案,但我还是将相对URL方法更改为:

public static final File getFileByRelativePathURL(String relativePath) {
        URL url = Thread.currentThread().getContextClassLoader().getResource(relativePath);
        File file = new File(url.getPath().replaceAll("%20", " "));
        return file;
    }

现在一切正常...愚蠢的我! 我真的必须用另一种方式来做;-)

1 个答案:

答案 0 :(得分:0)

由于JB Nizet的评论,我提出了一个解决方案,它可能更像是一种“肮脏的hack”,这是一种适当的解决方法,但它是解决当前问题的有效解决方案。

最初的错误是我的假设,即我可以将转义的URL路径用作文件路径,这显然是不正确的。因此,我通过修改我的相对路径方法来消除空格的逸出:

public static final File getFileByRelativePathURL(String relativePath) {
        URL url = Thread.currentThread().getContextClassLoader().getResource(relativePath);
        File file = new File(url.getPath().replaceAll("%20", " "));
        return file;
    }

这使得实际空间不能用'%20'替代,现在JUnit测试可在包含空格的所有路径中使用。但是,它不是其他空格或转义特殊字符的解决方案。

我将采纳建议并尝试解决我正在使用的旧API中File对象的必要性!

在我的代码中,我一定会喜欢Streams! :)