java.io.FileNotFoundException 即使文件路径正确
java.io.FileNotFoundException even when the file path is correct
我使用的代码:
package play;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
public class Play {
InputStream music;
public Play() {
URL url=getClass().getResource("/music/Whitewoods - College Kill Dream.mp3");
System.out.println(url.toString());
try {
FileInputStream fileInputStream=new FileInputStream(new File(url.toString()));
fileInputStream.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static void main(String args[]) {
new Play();
}
}
上面代码下面的行:
System.out.println(url.toString());
prints :
file:/C:/Users/eclipse-workspace/audioboard/bin/music/Whitewoods%20-%20College%20Kill%20Dream.mp3
如果我直接复制这个并把它放在 chrome 的 url 放置框里。文件打开但行:
FileInputStream fileInputStream=new FileInputStream(new File(url.toString()));
给出文件未找到错误。
错误堆栈:
java.io.FileNotFoundException: file:\C:\Users\eclipse-workspace\audioboard\bin\music\Whitewoods%20-%20College%20Kill%20Dream.mp3 (The filename, directory name, or volume label syntax is incorrect)
at java.base/java.io.FileInputStream.open0(Native Method)
at java.base/java.io.FileInputStream.open(FileInputStream.java:213)
at java.base/java.io.FileInputStream.<init>(FileInputStream.java:155)
at play.Play.<init>(Play.java:17)
at play.Play.main(Play.java:26)
谢谢你的帮助。
file:
位使您看到的实际上不是文件路径,而是 URL.
URL 有 toFile()
方法,它更接近您想要的,但仍然不是您实际要寻找的方法,即 getResourceAsStream
:
调用getResource
/getResourceAsStream
的合适方法是Play.class.getResource
,而不是getClass().getResource
。一个小尼特; getClass()
变体是非惯用的,并且严格地 worse/less 可读:如果 Play 曾经被子类化,它就会中断,而 Play.class.getResource
则不会。即使不相关,也最好使用更惯用的风格,正确答案严格来说是更多的场景。
通常,如果您将获得的资源转换为文件,您就会搞砸了; getResource
的要点是从找到 类 的同一位置为您提供资源,并且 它们不必是文件 。它们可以是 jar 中的条目(它们本身不是文件,并且不能作为 java.io.File
或 java.nio.path.Path
直接访问),通过网络拉入,即时生成- 任何事情,这就是抽象的重点。在这种情况下,您正在获取文件并 立即 将其转换为 InputStream
。不要那样做 - getResource 抽象可以做到这一点。
像所有资源一样,您不能像这样打开输入流。无论发生什么情况,您都需要确保它也已关闭。使用 try-with-resources 来确保这一点。
综合起来:
String songName = "Whitewoods - College Kill Dream.mp3";
try (var in = Play.class.getResourceAsStream("/music/" + songName)) {
// .... do something with 'in' here. It is an InputStream.
}
不需要关闭; try 构造将为您处理它。 'exits' 那些大括号的代码(通过 运行 结束,通过 return
或其他一些控制流,或通过异常)并不重要 - 输入流将被关闭。
您可以使用 File
构造函数 File(URI uri) 将 URL
url 转换为 URI
并将其作为参数传递给 File
构造函数如下:
File file = new File(url.toURI());
我使用的代码:
package play;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
public class Play {
InputStream music;
public Play() {
URL url=getClass().getResource("/music/Whitewoods - College Kill Dream.mp3");
System.out.println(url.toString());
try {
FileInputStream fileInputStream=new FileInputStream(new File(url.toString()));
fileInputStream.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static void main(String args[]) {
new Play();
}
}
上面代码下面的行:
System.out.println(url.toString());
prints :
file:/C:/Users/eclipse-workspace/audioboard/bin/music/Whitewoods%20-%20College%20Kill%20Dream.mp3
如果我直接复制这个并把它放在 chrome 的 url 放置框里。文件打开但行:
FileInputStream fileInputStream=new FileInputStream(new File(url.toString()));
给出文件未找到错误。
错误堆栈:
java.io.FileNotFoundException: file:\C:\Users\eclipse-workspace\audioboard\bin\music\Whitewoods%20-%20College%20Kill%20Dream.mp3 (The filename, directory name, or volume label syntax is incorrect)
at java.base/java.io.FileInputStream.open0(Native Method)
at java.base/java.io.FileInputStream.open(FileInputStream.java:213)
at java.base/java.io.FileInputStream.<init>(FileInputStream.java:155)
at play.Play.<init>(Play.java:17)
at play.Play.main(Play.java:26)
谢谢你的帮助。
file:
位使您看到的实际上不是文件路径,而是 URL.
URL 有 toFile()
方法,它更接近您想要的,但仍然不是您实际要寻找的方法,即 getResourceAsStream
:
调用
getResource
/getResourceAsStream
的合适方法是Play.class.getResource
,而不是getClass().getResource
。一个小尼特;getClass()
变体是非惯用的,并且严格地 worse/less 可读:如果 Play 曾经被子类化,它就会中断,而Play.class.getResource
则不会。即使不相关,也最好使用更惯用的风格,正确答案严格来说是更多的场景。通常,如果您将获得的资源转换为文件,您就会搞砸了;
getResource
的要点是从找到 类 的同一位置为您提供资源,并且 它们不必是文件 。它们可以是 jar 中的条目(它们本身不是文件,并且不能作为java.io.File
或java.nio.path.Path
直接访问),通过网络拉入,即时生成- 任何事情,这就是抽象的重点。在这种情况下,您正在获取文件并 立即 将其转换为InputStream
。不要那样做 - getResource 抽象可以做到这一点。像所有资源一样,您不能像这样打开输入流。无论发生什么情况,您都需要确保它也已关闭。使用 try-with-resources 来确保这一点。
综合起来:
String songName = "Whitewoods - College Kill Dream.mp3";
try (var in = Play.class.getResourceAsStream("/music/" + songName)) {
// .... do something with 'in' here. It is an InputStream.
}
不需要关闭; try 构造将为您处理它。 'exits' 那些大括号的代码(通过 运行 结束,通过 return
或其他一些控制流,或通过异常)并不重要 - 输入流将被关闭。
您可以使用 File
构造函数 File(URI uri) 将 URL
url 转换为 URI
并将其作为参数传递给 File
构造函数如下:
File file = new File(url.toURI());