[英]classLoader.getResourceAsStream returns an empty Stream in Testing
我有一个方法需要读取资源文件并将其作为 InputStream 传递给另一个方法。 显而易见的方法
InputStream is = classLoader.getResourceAsStream("filename.pem");
在实际运行应用程序时工作正常,但在测试中它返回一个空的 InputStream(用零填充)。 我不认为这是资源路径或任何问题,因为当我使用像"filex"
这样的无意义路径(filex 不存在)时,我得到一个实际的 null 指针异常而不是一个空的 stream。同样在调试器中空 Stream 的完整文件路径指向正确的路径,文件实际存储的位置(默认 class 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
具有填充了零的 Stream。 我无法完全解释这种行为。 如果我们在应用程序中使用一些修改过的 ClassLoader,我会仔细检查“getClass().getClassLoader().getClass()”,但它是来自sun.misc.Launcher$AppClassLoader
的原始类加载器。
所以我的问题是:
Files.readAllBytes()
。 我唯一的想法是:编码或字符集与它有关。 但据我所知, getResourceAsStream()
中没有像Charset
或StandardCharsets
这样的参数。
如果您将资源文件打开为 stream,您最终会在FileInputStream
周围得到一个BufferedInputStream
。
调用链如下:
java.lang.ClassLoader#getResource
返回一个URL
url.openStream()
被调用sun.net.www.protocol.file.Handler#createFileURLConnection
is = new BufferedInputStream(new FileInputStream(filename));
在sun.net.www.protocol.file.FileURLConnection#connect
is
这个作为InputStream
回来了您看到的是BufferedInputStream
的空内部缓冲区,一旦您开始从 InputStream 读取数据,它就会被使用。 查看FileInputStream 是否未缓冲以及为什么 BufferedInputStream 更快?
例如,如果您从全零的 InputStream 中读取,您将看到它确实包含数据:
Scanner scanner = new Scanner(inputStream, StandardCharsets.UTF_8.name());
String firstLine = scanner.next();
来自https://www.baeldung.com/convert-input-stream-to-string
您的解决方法有效,因为在您从资源 URL 中找到文件后,您实际上开始直接读取它。
那么您的测试可能会失败的原因是什么? 你不是想从你的测试用例中读取 stream 吗? 您如何使用/验证此输入流在您的测试中与实际应用程序中是否正确? 可能有问题。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.