首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Java IO 装饰者模式详解:FilterInputStream 与 FilterOutputStream 源码解析

     編輯:Java 相關知識

设计意图:装饰者模式

FilterInputStream 与 FilterOutputStream 是 Java IO 中装饰者模式的核心抽象:

  • 持有被装饰流引用(in/out)。
  • 将所有读写操作委托给被装饰流。
  • 子类可在委托前后插入额外逻辑(缓冲、数据类型转换、格式化输出等)。

FilterInputStream 源码解析 (JDK 1.7+)

public class FilterInputStream extends InputStream {
    protected volatile InputStream in; // 被装饰流

    protected FilterInputStream(InputStream in) { this.in = in; }

    // 所有读操作直接委托
    public int read() throws IOException { return in.read(); }
    public int read(byte[] b) throws IOException { return read(b, 0, b.length); }
    public int read(byte[] b, int off, int len) throws IOException { return in.read(b, off, len); }
    public long skip(long n) throws IOException { return in.skip(n); }
    public int available() throws IOException { return in.available(); }
    public void close() throws IOException { in.close(); }

    // mark/reset 委托
    public synchronized void mark(int readlimit) { in.mark(readlimit); }
    public synchronized void reset() throws IOException { in.reset(); }
    public boolean markSupported() { return in.markSupported(); }
}

关键点:

  • volatile 保证 in 引用可见性。
  • 构造器 protected,仅供子类调用。
  • 无额外逻辑,纯透明委托。

主要子类功能

FilterOutputStream 源码解析

public class FilterOutputStream extends OutputStream {
    protected OutputStream out;

    public FilterOutputStream(OutputStream out) { this.out = out; }

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

注意:write(byte[], off, len) 默认实现是循环调用 write(int),子类(如 BufferedOutputStream)通常重写为批量写入以提升性能。

主要子类功能

子类核心增强
BufferedInputStream内部维护 byte[] 缓冲区,减少底层读调用;支持 mark/reset。
DataInputStream提供 readInt()、readUTF() 等按机器无关格式读取基本类型;配合 DataOutputStream 实现跨平台数据交换。
LineNumberInputStream (已废弃)行号统计,建议用 LineNumberReader。
PushbackInputStream支持 unread() 回退字节,用于词法分析器。

典型组合用法

// 带缓冲的数据读写
try (DataOutputStream dos = new DataOutputStream(
         new BufferedOutputStream(new FileOutputStream("data.bin")))) {
    dos.writeInt(42);
    dos.writeUTF("hello");
}

try (DataInputStream dis = new DataInputStream(
         new BufferedInputStream(new FileInputStream("data.bin")))) {
    int i = dis.readInt();      // 42
    String s = dis.readUTF();   // hello
}

装饰链:FileOutputStream → BufferedOutputStream → DataOutputStream,各司其职,灵活组合。

源码阅读建议

  1. 从 FilterInputStream/OutputStream 理解委托结构。
  2. 对比 BufferedInputStream 与 BufferedOutputStream 的缓冲区管理差异。
  3. 研究 DataInputStream/OutputStream 如何处理字节序(大端序)与 UTF-8 编码。
  4. 关注 close() 链式关闭机制,理解 try-with-resources 的自动资源管理原理。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
子类核心增强
BufferedOutputStream内部缓冲区,批量刷新,重写 write(byte[], off, len) 高效拷贝。
DataOutputStream提供 writeInt()、writeUTF() 等,配合 DataInputStream 读写基本类型。
PrintStream自动 flush、不抛异常、提供 print/println 格式化输出,System.out 即实例。