从资源文件夹加载资源(如文本文件)时,最常用的方法是使用ClassLoader获取路径:
String path = getClass().getClassLoader().getResource("file.txt").getPath();
然后,您可以使用java中的任何读者来读取该文件的内容。但出于某种原因,Paths.get(path)
对路径不满意:
byte[] content = Files.readAllBytes(Paths.get(path))
-> throws java.nio.file.InvalidPathException when executed
ClassLoader.getResource(...)。getPath()正在返回:
/D:/Projects/myapp/build/resources/main/file.txt
Paths.get()
不喜欢它。显然/D
之后的':'是'非法字符'。 (注意路径似乎正确,文件实际上在那里)
哪一个导致问题? ClassLoader.getResource()
是否返回了无效路径,或者Paths.get()
是否无效?
稍后
似乎java中的路径有多种不同的格式。各种框架似乎并不完全同意什么是正确的和什么是错的,因此它们创建和接受的路径之间存在各种差异。
在此示例中,Paths.get()
实际上并不期望路径中的前导斜杠:
/D:/Projects/myapp/build/resources/main/vertex.vs.glsl <- EVIL
D:/Projects/myapp/build/resources/main/vertex.vs.glsl <- OK
我认为现在的问题是:如何正确清理ClassLoader.getResource()
返回的文件路径,以便与Paths.get()
正确使用?它们的两种文件路径格式之间是否还有其他差异?
答案 0 :(得分:1)
/D:/Projects/myapp/build/resources/main/file.txt
中的第一个斜杠只是意味着这是一条绝对路径:见Class.getResource 更新以回答评论:&#34;那么为什么Paths.get()不接受绝对路径?&#34;
Paths.get()
确实接受绝对路径
但是你必须传递一个有效的(文件)路径 - 在你的情况下你直接传递URL路径(这不是一个有效的文件路径)。
getClass().getClassLoader().getResource("file.txt")
时,会返回一个网址:file:/D:/Projects/myapp/build/resources/main/file.txt
file:
/D:/Projects/myapp/build/resources/main/file.txt
InvalidPathException
要将网址路径转换为有效的文件路径,您可以使用Paths.get(URI)方法,如下所示:
URL fileUrl = getClass().getClassLoader().getResource("file.txt");
String filePath = Paths.get(fileUrl.toURI());
// now you have a valid file-path: D:/Projects/myapp/build/resources/main/file.txt
答案 1 :(得分:0)
请查看getClass().getClassLoader().getResource("file.txt")
的结果。它是一个URL。使用getPath()
,您只需检索该URL的路径部分,忽略协议和服务器部分。将路径部分作为文件打开可能在某些情况下(在文件语法和URL路径语法匹配的简单情况下),但不要在生产代码中执行。
为什么呢?当您离开IDE并将应用程序作为JAR或WAR交付时,资源将驻留在ZIP压缩文件中,并且没有文件&#34; file.txt&#34;您可以打开,只有JAR或WAR文件中的条目。
正如@TmTron所指出的,我还建议使用ClassLoader.getResourceAsStream()
。这将适用于所有情况。