【问题标题】:Why does PrintStream extend FilterOutputStream and not OutputStream?为什么 PrintStream 扩展 FilterOutputStream 而不是 OutputStream?
【发布时间】:2013-07-20 19:29:30
【问题描述】:

System.outSystem.err都是PrintStreams;和PrintStream 扩展FilterOutputStream

来自FilterOutputStream的javadoc:

这个类是过滤输出流的所有类的超类。这些流位于已经存在的输出流(底层输出流)之上,它用作其基本数据接收器,但可能会在此过程中转换数据或提供额外的功能。

FilterOutputStream 类本身只是简单地用将所有请求传递到底层输出流的版本覆盖了 OutputStream 的所有方法。 FilterOutputStream 的子类可能会进一步覆盖其中一些方法,并提供额外的方法和字段。

(强调我的)

FilterOutputStream 本身扩展了OutputStream

我在这里不知所措。 PrintStream 有什么理由需要扩展 FilterOutputStream 而不是 OutputStream

示例代码赞赏...

【问题讨论】:

    标签: java


    【解决方案1】:

    FilterOutputStream 应用组合模式,它将所有调用委托给其实例变量out

    /* The underlying output stream to be filtered. */
    protected OutputStream out;
    

    FilterOutputStream 也有抽象类OutputStream 的默认实现:

    public void write(int b) throws IOException {
        out.write(b);
    }
    
    public void write(byte b[]) throws IOException {
        write(b, 0, b.length);
    }
    
    public void write(byte b[], int off, int len) throws IOException {
        if ((off | len | (b.length - (len + off)) | (off + len)) < 0)
            throw new IndexOutOfBoundsException();
    
        for (int i = 0 ; i < len ; i++) {
            write(b[off + i]);
        }
    }
    
    public void flush() throws IOException {
        out.flush();
    }
    
    public void close() throws IOException {
        try {
          flush();
        } catch (IOException ignored) {
        }
        out.close();
    }
    

    现在,包括PrintStream 在内的任何类都可以扩展FilterOutputStream 并覆盖相应的方法。请注意,他们仍然需要将呼叫委托给out。例如PrintStream#flush():

    public void flush() {
        synchronized (this) {
            try {
                ensureOpen();
                out.flush();
            }
            catch (IOException x) {
                trouble = true;
            }
        }
    }
    

    【讨论】:

      【解决方案2】:

      PrintStream 必须实现各种过滤器,处理字符编码,最终将非字符数据打印为字符。

      FilterOutputStream 的一般约定最适合这个,所以这是使用的类。

      【讨论】:

      • 你在这里基本上是在告诉FilterOutputStream做作曲?
      • @fge 它可以处理任何类型的过滤或数据更改,在这种情况下是字符处理或组合。
      【解决方案3】:

      任何高层Stream需要对嵌套的低层Stream的输入或输出进行过滤,都需要先扩展FilteredOutputStream,InputStreams也是如此。因此,all 的高级 OutputStreams 扩展 FilteredOutputStream 类是有道理的,换句话说,所有允许并且实际上需要嵌套其他 Streams 的 Streams函数,必须扩展这个类。

      我不知道这个类在内部做了什么,但我想它会以某种方式处理数据以允许更高级别的流能够理解它们。要了解更多信息,我猜您将不得不深入研究源代码。

      【讨论】:

      • 我认为 PrintStream 扩展了 FilterOutputStream 以对字符及其编码进行一些额外的操作和计算。不能在同一个 PrintStream 中混合字符(字符串)和二进制数据,这可能是一个线索。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-01-14
      • 1970-01-01
      • 2011-04-13
      • 2011-08-07
      • 1970-01-01
      • 2013-07-23
      相关资源
      最近更新 更多