Java标准IO不支持多路复用,但可通过TeeInputStream模拟流复制或单线程解析分发实现近似效果;真实高并发场景应改用NIO的Selector机制。

Java 标准 IO(java.io)本身不支持多路复用,也无法直接实现类似 NIO 中 Selector 的事件驱动分发;所谓“IO 流的多路复用”在传统阻塞 IO 模型中并不存在。但你可以通过组合设计模式、线程协作与流封装,模拟数据分发与输入流复制行为。关键在于区分两个概念:
一、输入流复制(Stream Tee / Split)
将一个输入流的数据同时写入多个目标(如文件、内存、网络),或生成多个独立可读副本。Java 原生不提供 TeeInputStream,但可手动实现:
- 用
ByteArrayOutputStream先缓冲全部数据,再创建多个ByteArrayInputStream—— 适合小数据量、内存充足场景 - 使用装饰器模式:自定义
TeeInputStream,在read()时同步写入一个或多个OutputStream(如FileOutputStream或PipedOutputStream) - 示例核心逻辑:
public class TeeInputStream extends InputStream {
private final InputStream in;
private final OutputStream[] outs;
public int read() throws IOException {
int b = in.read();
if (b != -1) for (OutputStream out : outs) out.write(b);
return b;
}
}
二、“多路复用式”分发(模拟 Selector 行为)
传统 IO 无法真正多路复用,但可通过以下方式近似实现“单入口、多出口”的路由分发:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 用一个主线程持续读取源流(如
System.in或Socket.getInputStream()),解析协议头(如长度前缀、分隔符、JSON 字段)识别目标通道 - 根据规则将字节块转发给不同处理线程或
PipedOutputStream对应的PipedInputStream - 配合
ConcurrentHashMap管理动态注册的“下游消费者”,实现运行时添加/移除接收端 - 注意:该方案本质是单线程读 + 多线程写,不是内核级 I/O 复用,吞吐受限于源流读取速度和锁竞争
三、推荐替代方案:改用 NIO
若真实需求是高并发、低延迟的多连接数据分发,应放弃传统 IO,转向 java.nio:
立即学习“Java免费学习笔记(深入)”;
- 用
ServerSocketChannel+Selector接收多个客户端连接 - 每个
SocketChannel注册OP_READ,在单线程中轮询就绪通道 - 读取到数据后,用
ByteBuffer分发至不同业务处理器(如按 session ID 路由、广播、过滤) - 如需复制数据,可调用
buffer.duplicate()或buffer.slice()获取视图,避免拷贝
四、实用工具类参考
Apache Commons IO 提供了开箱即用的辅助类:
-
org.apache.commons.io.input.TeeInputStream:已实现基础复制功能 -
org.apache.commons.io.output.TeeOutputStream:用于输出端分流 -
org.apache.commons.io.IOUtils.copy():安全高效完成流复制,支持大文件和进度回调

















