简体   繁体   English

Java中的null(输入/输出)流API的用例是什么?

[英]What is the use case for null(Input/Output)Stream API in Java?

With Java 11, I could initialize an InputStream as: 使用Java 11,我可以将InputStream初始化为:

InputStream inputStream = InputStream.nullInputStream();

But I am unable to understand a potential use case of InputStream.nullInputStream or a similar API for OutputStream ie OutputStream.nullOutputStream . 但我无法理解InputStream.nullInputStream的潜在用例或OutputStream的类似API,即OutputStream.nullOutputStream

From the API Javadocs, I could figure out that it 从API Javadocs,我可以弄清楚它

Returns a new InputStream that reads no bytes . 返回不读取任何字节的新InputStream The returned stream is initially open. 返回的流最初是打开的。 The stream is closed by calling the close() method. 通过调用close()方法关闭流。

Subsequent calls to close() have no effect. close()后续调用无效。 While the stream is open, the available() , read() , read(byte[]) , ... skip(long) , and transferTo() methods all behave as if end of stream has been reached. 当流打开时, available()read()read(byte[]) ,... skip(long)transferTo()方法都表现得好像已经到达流的末尾。

I went through the detailed release notes further which states: 我进一步详细说明了这些说明:

There are various times where I would like to use methods that require as a parameter a target OutputStream/Writer for sending output, but would like to execute those methods silently for their other effects. 有很多次我想使用需要作为目标OutputStream / Writer的参数来发送输出的方法,但是想要为其他效果静默执行这些方法。

This corresponds to the ability in Unix to redirect command output to /dev/null, or in DOS to append command output to NUL. 这相当于Unix将命令输出重定向到/ dev / null,或者在DOS中将命令输出附加到NUL的能力。

Yet I fail to understand what are those methods in the statement as stated as .... execute those methods silently for their other effects . 然而,我无法理解陈述中声明的那些方法是什么...... 为了其他效果而默默地执行这些方法 (blame my lack of hands-on with the APIs) (归咎于我没有动手使用API​​)

Can someone help me understand what is the usefulness of having such an input or output stream with a help of an example if possible? 有人可以帮助我理解在可能的情况下借助示例获得这样的输入或输出流有什么用处吗?


Edit : One of a similar implementation I could find on browsing further is apache-commons' NullInputStream , which does justify the testing use case much better. 编辑 :我在浏览时可以找到的类似实现之一是apache-commons的NullInputStream ,它更好地证明了测试用例的合理性。

Sometimes you want to have a parameter of InputStream type, but also to be able to choose not to feed your code with any data. 有时您希望拥有InputStream类型的参数,但也可以选择不使用任何数据提供代码。 In tests it's probably easier to mock it but in production you may choose to bind null input instead of scattering your code with if s and flags. 在测试中,它可能更容易嘲笑,但在生产中,你可以选择绑定空输入 ,而不是与散射你的代码if S和标志。

compare: 相比:

class ComposableReprinter {
    void reprint(InputStream is) throws IOException {
        System.out.println(is.read());
    }

    void bla() {
        reprint(InputStream.nullInputStream());
    }
}

with this: 有了这个:

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);
    }
}

or this: 或这个:

class NullableReprinter {
    void reprint(InputStream is) throws IOException {
        if (is != null) {
            System.out.println(is.read());
        }
    }
    void bla() {
        reprint(null);
    }
}

It makes more sense with output IMHO. 输出恕我直言更有意义。 Input is probably more for consistency. 输入可能更符合一致性。

This approach is called Null Object : https://en.wikipedia.org/wiki/Null_object_pattern 这种方法称为Null Objecthttps//en.wikipedia.org/wiki/Null_object_pattern

I see it as a safer (1) and more expressive (2) alternative to initialising a stream variable with null . 我认为它是一个更安全(1)和更具表现力的(2)替代初始化流变量与null

  1. No worries about NPEs. 不用担心NPE。
  2. [Output|Input]Stream is an abstraction. [Output|Input]Stream是一种抽象。 In order to return a null/empty/mock stream, you had to deviate from the core concept down to a specific implementation. 为了返回null / empty / mock流,您必须将核心概念偏离到特定实现。

I think nullOutputStream is very easy and clear: just to discard output (similar to > /dev/null ) and/or for testing (no need to invent an OutputStream ). 我认为nullOutputStream非常简单明了:只是丢弃输出(类似于> /dev/null )和/或进行测试(不需要发明OutputStream )。

An (obviously basic) example: 一个(显然是基本的)例子:

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?

Regarding nullInputStream it's probably more for testing (I don't like mocks) and APIs requiring an input stream or (this now being more probable) delivering an input stream which does not contain any data, or you can't deliver and where null is not a viable option: 关于nullInputStream它可能更多用于测试(我不喜欢模拟)和需要输入流的API或(现在更可能)提供不包含任何数据的输入流,或者您无法传递,而null是不是一个可行的选择:

importer.importDocument("name", /* input stream... */);
InputStream inputStream = content.getInputStream(); // better having no data to read, then getting a null

When you test that importer, you can just use a nullInputStream there, again instead of inventing your own InputStream or instead of using a mock. 当你测试那个导入器时,你可以再使用nullInputStream ,而不是发明你自己的InputStream或者不使用mock。 Other use cases here rather look like a workaround or misuse of the API ;-) 这里的其他用例看起来像是变通方法或滥用API ;-)

Regarding the return of an InputStream : that rather makes sense. 关于InputStream的返回:这是有道理的。 If you haven't any data you may want to return that nullInputStream instead of null so that callers do not have to deal with null and can just read as they would if there was data. 如果您没有任何数据,您可能希望返回nullInputStream而不是null这样调用者就不必处理null ,只能读取数据时的情况。

Finally, these are just convenience methods to make our lifes easier without adding another dependency ;-) and as others already stated (comments/answers), it's basically an implementation of the null object pattern . 最后,这些只是方便的方法,使我们的生活更容易,而不添加另一个依赖;-)和其他已经说明(评论/答案),它基本上是空对象模式的实现

Using the null*Stream might also have the benefit that tests are executed faster... if you stream real data (of course... depending on size, etc.) you may just slow down your tests unnecessarily and we all want tests to complete fast, right? 使用null*Stream可能还有一个好处,即测试执行得更快...如果您流式传输真实数据(当然......取决于大小等),您可能只是不必要地减慢测试速度,我们都希望测试到完全快,对吗? (some will put in mocks here... well...) (有些人会把嘲笑放在这里......好吧......)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM