22

我一直在阅读InputStreamFileInputStreamByteArrayInputStream以及它们的使用似乎很清楚(输出流也是如此)。

我正在努力的是了解FilterInputStream 和 FilterOutputStream的使用:

  • 与其他流类相比,使用它有什么优势?
  • 我应该什么时候使用它?
  • 请提供理论解释和基本示例。
4

3 回答 3

25

FilterInputStream装饰器模式的一个例子。

这个类必须扩展,因为它的构造函数是protected. 派生类会添加额外的功能,但仍会公开InputStream.

例如,aBufferedInputStream提供底层输入流的缓冲以更快地读取数据,并在使用DigestInputStream数据时计算数据的加密哈希。

您将使用它向依赖于InputStreamOutputStreamAPI 的现有代码添加功能。例如,假设您使用某个库将数据保存到OutputStream. 数据增长过大,因此您想要添加压缩。无需修改数据持久性库,您可以修改您的应用程序,以便它“装饰”它当前使用ZipOutputStream. 该库将使用该流,就像它使用缺少压缩的旧版本一样。

于 2013-07-05T18:12:31.180 回答
4

当您想要装饰数据流时使用它们。

请记住,这些流类实例将自己包裹在另一个流实例(无论是否是其中一个的另一个子类)周围,并添加一些功能,添加一些处理,在数据通过时对数据进行一些更改。

例如,您可能希望从某个流中删除所有多个空格。您创建自己的 FilterInputStream 子类并覆盖该read()方法。我不会打扰所有细节,但这里有一些用于子类中方法的 sorta-java:

private boolean lastWasBlank = false;
public int read() {
    int chr = super.read();
    if (chr == ' ') {
        if (lastWasBlank) {
            return read();
        } else {
            lastWasBlank = true;
        }
    } else {
        lastWasBlank = false;
    }
    return chr;
}

在现实生活中,您可能也会混淆其他两种read()方法。

其他用途:

  • 记录流过流的所有内容
  • 复制“tee”实用程序,以便以两种方式处理正在读取的流。
  • 在 Windows、Mac 和 Unix/Linux 格式之间转换行尾
  • 添加延迟以模拟调制解调器或串行端口或无线网络连接等慢速传输方法。
于 2013-07-05T18:21:08.517 回答
2

FilterInputStreamFilterOutputStream可以减轻希望实现自己的输入/输出流的开发人员的工作。诸如BufferedInputStream之类的实现可以在基本 API 周围添加自己的装饰,InputStream同时委托super类 - 在这种情况下为 FilteredInputStream - 他们不需要覆盖的方法。

既不FilterInputStream是也不FilterOutputStream是为最终用户直接使用而设计的。

于 2018-04-25T15:47:20.717 回答