当路径包含任何空格时,无法在 Java 中加载文件,例如%20
Loading files in a Java ist not working when path contains any whitespaces e.g. %20
我查看了很多关于 Java 文件和路径问题的答案,甚至有些路径中有白色 spaces,但没有回答我想问的问题:
为什么以下代码在非白色 space 目录中有效,否则为什么会失败?
我将我的问题简化为问题的基本要素,所以我希望任何人都可以向我解释问题;-)
我有一个旧的 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\not working\imageload\
我仔细查看了生成的文件实例,目录中的 space 已正确转义到此文件对象路径:
file = D:\Temp\not%20working\imageload\target\test-classes\testset\black.jpg
但是%20肯定有问题,因为按照文件Class.
的"exists()"方法找不到文件
我希望这个问题对你们中的许多人来说可能是显而易见的,但我仍然希望 "theFile.exists()" returns 在有或没有 whitespaces 的任何目录中都是正确的。
我做错了什么?
更新:有人问我我的问题是否与这篇文章重复:
- Java read file with whitespace in its path
不幸的是,该解决方案没有解决我寻找正确相对路径的冲动。相反,它将绝对路径传递给文件构造函数。
但是结合 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;
}
现在一切正常...愚蠢的我!
我真的必须用另一种方式来做 ;-)
感谢 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;
}
这从“%20”替换中生成了真正的空格,现在 JUnit 测试可以在所有包含空格的路径中运行。不过,它不是其他空格或转义特殊字符的解决方案。
我会采纳建议并尝试解决旧 API 我正在使用的 File 对象的必要性!
在我的代码中,我一定会喜欢 Streams! :)
我查看了很多关于 Java 文件和路径问题的答案,甚至有些路径中有白色 spaces,但没有回答我想问的问题:
为什么以下代码在非白色 space 目录中有效,否则为什么会失败?
我将我的问题简化为问题的基本要素,所以我希望任何人都可以向我解释问题;-)
我有一个旧的 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\not working\imageload\
我仔细查看了生成的文件实例,目录中的 space 已正确转义到此文件对象路径:
file = D:\Temp\not%20working\imageload\target\test-classes\testset\black.jpg
但是%20肯定有问题,因为按照文件Class.
的"exists()"方法找不到文件我希望这个问题对你们中的许多人来说可能是显而易见的,但我仍然希望 "theFile.exists()" returns 在有或没有 whitespaces 的任何目录中都是正确的。
我做错了什么?
更新:有人问我我的问题是否与这篇文章重复:
- Java read file with whitespace in its path
不幸的是,该解决方案没有解决我寻找正确相对路径的冲动。相反,它将绝对路径传递给文件构造函数。
但是结合 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;
}
现在一切正常...愚蠢的我! 我真的必须用另一种方式来做 ;-)
感谢 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;
}
这从“%20”替换中生成了真正的空格,现在 JUnit 测试可以在所有包含空格的路径中运行。不过,它不是其他空格或转义特殊字符的解决方案。
我会采纳建议并尝试解决旧 API 我正在使用的 File 对象的必要性!
在我的代码中,我一定会喜欢 Streams! :)