Java 尝试读取文件时出现奇怪的NoSuchFileException

Java 尝试读取文件时出现奇怪的NoSuchFileException,java,resources,Java,Resources,成功地给了我一个密钥文件。如果我现在用以下内容列出路径: File privateKeyFile = new File(this.getClass().getClassLoader().getResource("privateKey").getFile()); 调试成功向我显示文件的路径: 文件:/Users/me/.m2/repository/com/xx/xyz/abc/encryption/1.0/encryption-1.0.jar/私钥 -- 但是,只要我试着用 privateKey

成功地给了我一个密钥文件。如果我现在用以下内容列出路径:

File privateKeyFile = new File(this.getClass().getClassLoader().getResource("privateKey").getFile());
调试成功向我显示文件的路径:

文件:/Users/me/.m2/repository/com/xx/xyz/abc/encryption/1.0/encryption-1.0.jar/私钥

--

但是,只要我试着用

privateKeyFile.toPath()
我明白了

方法引发了“java.nio.file.NoSuchFileException”异常


这确实令人困惑,我尝试将
getResource()
更改为
getResource(“/privateKey”)-但是错误要快得多,实际上NPE在尝试创建
新文件()时是正确的,因此文件必须存在,如我上面所示???

由于文件在Jar中,Java无法将其识别为实际的“文件”。因此,你必须以不同的方式阅读。根据,你可能会读到这样的内容:

InputStream in=getClass().getResourceAsStream(“privatekey”);
字节[]数组=新字节[in.available()];
in.read(数组);
如果您使用的是Java 9+,则可能如下所示:

InputStream in=getClass().getResourceAsStream(“privatekey”);
字节[]数组=in.readAllBytes();
编辑: 因为有些人想要一个包含read函数的完整源代码的示例,所以您可以这样做:

InputStream in=getClass().getResourceAsStream(“privatekey”);
列表字节=新的ArrayList();
while(in.available()>0){
byte[]b=新字节[in.available()];
in.改为(b);
字节。addAll(b);
}
字节[]数组=(字节[])字节。toArray();

文件的构造函数不关心路径字符串是否实际指向现有文件,因此不要依赖路径字符串来检查文件是否存在。改为使用
privateKeyFile.exists()
(如果文件存在,则返回
true
)。据我所见,文件确实不存在,或者您提供的路径不正确,因此
exists()
应返回false。

感谢回复,我现在成功地使用了此代码

Files.readAllBytes(privateKeyFile.toPath())
我最初尝试了给出的另一种方法,但这导致了BadPaddingException,可能是因为没有完全读取文件

//working
InputStream publicKeyStream = this.getClass().getClassLoader().getResourceAsStream("publicKey");
toByteArray(privateKeyStream));

文件存在于文件系统中。您的资源位于jar文件中。所以它不是一个文件。不要使用文件IO从位于jar文件内的类路径读取资源,因为它们不是文件。如果需要URL,则getResource()会提供该URL。如果您需要字节,那么getResourceAsStream()会提供这些字节。@JBNizet我是按照这个指南做的。你能推荐另一个吗?不。但是javadoc是你的朋友。URL的getFile()方法不能保证返回有效的文件名。它只返回URL的一部分,所有百分比转义都保持不变。
available()
不返回可从流中读取的总字节数。你的代码不正确。它可以工作,但也可能无法读取所有字节。“返回可读取字节数的估计值”返回可从该输入流中读取(或跳过)而不阻塞的字节数的估计值。所以,这是一个估计值,这个估计值是在没有阻塞的情况下可以读取的字节数。所以,正如我所说的,这显然不是可以从流中读取的总字节数。我理解你的整个spiel,但这只是一个例子。这不是实际的实现。只是试图解释它是如何被读取的。为什么你要用不正确的代码来解释它,而不是用正确的代码来解释它,或者如果你不能正确地编写它,就根本没有代码?这实际上是不正确的。文件仅实际访问文件系统中的文件。OP请求访问Jar文件中的一个文件,这是一个不同的进程。事实上,这是一个不同的进程,但正如我所说,没有任何东西可以阻止您向file()构造函数传递错误的路径。事实上,只有当您实际尝试访问该文件时,问题才会出现。我所说的是正确的,但我明白我没有提供解决方案。
//The incorrect code:

byte[] array = new byte[in.available()];
in.read(array);