使用Java 11,我可以将InputStream
初始化为:
InputStream inputStream = InputStream.nullInputStream();
但是我无法理解InputStream.nullInputStream
或OutputStream
的类似API的潜在用例
即OutputStream.nullOutputStream
。
从API Javadocs中,我可以弄清楚它
返回一个新的
InputStream
,它不读取任何字节。返回的流是 最初是开放的。通过调用close()方法关闭流。随后对
close()
的调用无效。流打开时,available()
,read()
,read(byte[])
,...skip(long)
和transferTo()
方法的行为就像流的结尾 已经达到。
我进一步研究了detailed release notes,其中指出:
在很多时候我想使用需要的方法 发送输出的目标OutputStream / Writer作为参数,但是 希望静默地执行这些方法以达到其他效果。
这对应于Unix中将命令输出重定向到的功能 / dev / null,或在DOS中将命令输出附加到NUL。
但是,我仍然无法理解语句中陈述的那些方法。...为其他效果而静默执行这些方法。 (归咎于我缺乏动手使用API)
如果可能的话,有人可以帮助我理解具有这样的输入或输出流的用处吗?
编辑 :我可以在进一步浏览中找到的类似实现之一是apache-commons的NullInputStream
,它可以更好地证明测试用例的合理性
答案 0 :(得分:18)
有时您希望具有InputStream类型的参数,但又希望选择不向代码提供任何数据。在测试中,模拟它可能更容易,但是在生产中,您可以选择绑定空输入,而不是使用if
和标志分散代码。
比较:
class ComposableReprinter {
void reprint(InputStream is) throws IOException {
System.out.println(is.read());
}
void bla() {
reprint(InputStream.nullInputStream());
}
}
与此:
class ControllableReprinter {
void reprint(InputStream is, boolean for_real) throws IOException {
if (for_real) {
System.out.println(is.read());
}
}
void bla() {
reprint(new BufferedInputStream(), false);
}
}
或者这个:
class NullableReprinter {
void reprint(InputStream is) throws IOException {
if (is != null) {
System.out.println(is.read());
}
}
void bla() {
reprint(null);
}
}
使用输出恕我直言更有意义。输入可能更多是为了保持一致性。
答案 1 :(得分:12)
与使用null
初始化流变量相比,我认为它是一种更安全(1)和更具表达性(2)的选择。
[Output|Input]Stream
是一个抽象。为了返回空/空/模拟流,您必须从核心概念转向特定的实现。答案 2 :(得分:3)
我认为nullOutputStream
非常简单明了:仅丢弃输出(类似于> /dev/null
)和/或进行测试(无需发明OutputStream
)。
(显然是基本的)示例:
OutputStream out = ... // an easy way to either print it to System.out or just discard all prints, setting it basically to the nullOutputStream
out.println("yeah... or not");
exporter.exportTo(out); // discard or real export?
关于nullInputStream
,它可能更适合测试(我不喜欢模拟)和需要输入流的API,或者(现在更有可能)提供不包含任何数据的输入流,或者您可以无法交付,而null
并不可行:
importer.importDocument("name", /* input stream... */);
InputStream inputStream = content.getInputStream(); // better having no data to read, then getting a null
在测试该导入程序时,可以再次在其中使用nullInputStream
,而不是发明自己的InputStream
或使用模拟程序。这里的其他用例看起来像是API的变通办法或滥用;-)
关于InputStream
的返回:这很有意义。如果您没有任何数据,则可能要返回那个nullInputStream
而不是null
,这样呼叫者就不必处理null
了,只要有数据就可以读取它们
最后,这些只是使我们的生活更轻松而无需添加其他依赖项的便利方法;-),并且正如其他人已经指出的那样(评论/答案),它基本上是null object pattern的实现。
使用null*Stream
的好处还在于可以更快地执行测试...如果您流式传输实际数据(当然,取决于大小等),则可能会不必要地减慢测试速度,并且我们都希望测试能快速完成,对吧? (有些人会在这里放模拟……好吧……)