classLoader.getResourceasstream返回测试中的空流
我有一种方法需要读取资源文件并将其作为输入流传递给另一种方法。显而易见的方法
InputStream is = classLoader.getResourceAsStream("filename.pem");
在实际运行应用程序时可以正常工作,但是在测试时,它返回一个空输入式(填充零)。我认为资源路径或其他任何问题都不是问题,因为当我使用“ filex”
(Filex不存在)时,我会得到实际的null指针异常,而不是空流。同样,在调试器中,空流的完整文件路径指向正确存储文件的正确路径(默认类root)。
此外,在以下解决方法的情况下,它可以工作:
File file = new File(classLoader.getResource("filename.pem").getFile());
String fileS= new String(Files.readAllBytes(file.toPath()), Charset.defaultCharset());
InputStream is = classLoader.getResourceAsStream("filename.pem");
InputStream is2 = new ByteArrayInputStream(fileS.getBytes(StandardCharsets.UTF_8));
在此示例中,is2
在InputStream中具有文件的实际内容,而is
具有填充零的流。我无法完全解释这种行为。如果我们在应用程序中使用一些修改后的classloader,我将与'getClass()。getClassLoader()。getClass()。
所以我的问题是:
- 为什么解决方法可以起作用,而不是经典的方法?
- 为什么仅在测试课程中失败?
- 有没有办法使它起作用?解决方法是更多的代码行,也需要由于
files.readallBytes()
呼叫而需要捕获IOException。
我剩下的唯一想法是:编码或Charset与它有关。但据我所知,getResourceasstream()
喜欢chods> charset
或standardCharsets
。
I have a method where I need to read a resource file and pass it to another method as an InputStream. The obvious approach
InputStream is = classLoader.getResourceAsStream("filename.pem");
works fine when actually running the application, but in testing it returns an empty InputStream (filled with zeros). I don't think its a problem with the resource path or anything, because when I use a nonsense path like "filex"
(filex does not exist), I get an actual null pointer exception and not an empty stream. Also in debugger the complete file path of the empty Stream points to the correct path, where the file actually is stored (default class root).
Furthermore, with the following workaround it works:
File file = new File(classLoader.getResource("filename.pem").getFile());
String fileS= new String(Files.readAllBytes(file.toPath()), Charset.defaultCharset());
InputStream is = classLoader.getResourceAsStream("filename.pem");
InputStream is2 = new ByteArrayInputStream(fileS.getBytes(StandardCharsets.UTF_8));
In this example is2
has the actual content of the file in the InputStream, while is
has an Stream filled with zeros. I can't quite explain that behaviour. I double checked with 'getClass().getClassLoader().getClass()' if we use some modified ClassLoader in the Application, but it is the original one from sun.misc.Launcher$AppClassLoader
.
So my questions are:
- Why does the workaround work but not the classic approach?
- Why does it fail only in test class?
- Is there a way to make it work? The workaround is more lines of code and also need to catch IOException because of the
Files.readAllBytes()
call.
The only idea I had left: the encoding or charset has something to do with it. But to my knowledge there is no parameter in getResourceAsStream()
like Charset
or StandardCharsets
.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
如果将资源文件作为流打开,则最终会在
BufferedInputStream
周围围绕fileinputStream
。呼叫链如下:
java.lang.classloader#getResource
返回url
sun.net.www.protocol.file.file.handler#createfileurlconnection
is = new BufferedInputStream(new FileInputStream(fileName(filename));
insun sun 。
BufferedInputStream
,一旦您开始从InputStream读取,它就会立即使用。参见 fileInputStream note note offileInputStream noted notefere >
例如,如果您从输入流读取所有零的读取物,您会看到它确实包含数据:
https://www.baeldung.com/convert-input-stream-to-string
您的解决方法可以正常工作,因为您实际上是从资源URL找到文件后,实际上可以直接开始读取它。
因此,您的测试可能会失败;您是否不尝试从测试柜中的流中阅读?您如何在测试中与实际应用程序中使用此输入流,您如何使用/验证?可能有问题。
If you open a resource file as a stream, you end up with a
BufferedInputStream
around aFileInputStream
.The call chain is as follows:
java.lang.ClassLoader#getResource
returns anURL
url.openStream()
is calledsun.net.www.protocol.file.Handler#createFileURLConnection
is = new BufferedInputStream(new FileInputStream(filename));
insun.net.www.protocol.file.FileURLConnection#connect
is
back asInputStream
What you're seeing is the empty internal buffer of the
BufferedInputStream
, which will be used as soon as you start reading from the InputStream.See is FileInputStream not buffered and why BufferedInputStream is faster?
If you for example read from the InputStream with all zero's, you will see it does actually contain data:
From https://www.baeldung.com/convert-input-stream-to-string
Your workaround works, because after you've located the file from the resource URL you actually start reading it directly.
So what might be failing in your test; are you not trying to read from the stream in your testcase? How are you using/validating if this inputstream is correct in your test vs the real application? There might be the problem.