Wrayの知识库 Wrayの知识库
首页
  • Java 基础
  • Java 集合
  • Java 并发
  • Java IO
  • JVM
  • Spring Framework
  • Spring Boot
  • Spring Cloud
  • Spring Security
  • MySQL
  • Redis
  • 计算机基础
  • 操作系统原理
  • Linux
  • MacOS
  • Windows
  • 系统工程与研究专题
  • AI 基础
  • 大模型基础
  • Prompt 工程
  • RAG 检索增强生成
  • Agent 智能体
  • AI 应用开发
  • AI 工程化
  • AI 安全与治理
  • AI 面试与设计题
  • 纸质书
  • 电子书
  • 学习课程
疑难杂症
GitHub (opens new window)
首页
  • Java 基础
  • Java 集合
  • Java 并发
  • Java IO
  • JVM
  • Spring Framework
  • Spring Boot
  • Spring Cloud
  • Spring Security
  • MySQL
  • Redis
  • 计算机基础
  • 操作系统原理
  • Linux
  • MacOS
  • Windows
  • 系统工程与研究专题
  • AI 基础
  • 大模型基础
  • Prompt 工程
  • RAG 检索增强生成
  • Agent 智能体
  • AI 应用开发
  • AI 工程化
  • AI 安全与治理
  • AI 面试与设计题
  • 纸质书
  • 电子书
  • 学习课程
疑难杂症
GitHub (opens new window)
  • Java章节编写规范
  • Java基础

  • Java集合

  • Java并发

  • Java IO

    • Java IO概述
    • IO基础

    • 常用IO流

    • 文件与目录操作

    • Java NIO

      • NIO概述
      • Buffer缓冲区
      • Channel通道
        • 1. Channel 和 Stream 的区别
        • 2. FileChannel
        • 3. position
        • 4. force
        • 5. transferTo 和 transferFrom
        • 6. SocketChannel
        • 7. ServerSocketChannel
        • 专家实践清单
        • Tips 快问快答
        • 8. 总结
      • Selector多路复用
      • SocketChannel网络编程
      • NIO与IO对比
    • 高级主题

    • 实践与性能优化

    • 面试与设计题

    • IO实践速查

  • JVM

目录

Channel通道

Channel 是 NIO 中连接数据源和数据目标的通道。它和传统流类似,都用于读写数据,但 Channel 通常是双向的,并且和 Buffer 配合使用。

# 1. Channel 和 Stream 的区别

对比项 Stream Channel
数据模型 面向流 面向缓冲区
方向 通常单向 通常双向
非阻塞 不支持或支持有限 网络 Channel 支持
配合对象 byte[]、char[] Buffer
典型 API InputStream、OutputStream FileChannel、SocketChannel

# 2. FileChannel

FileChannel 用于文件读写。

try (FileChannel channel = FileChannel.open(
        Path.of("data.txt"),
        StandardOpenOption.READ)) {

    ByteBuffer buffer = ByteBuffer.allocate(1024);
    int len = channel.read(buffer);
}

写入文件:

try (FileChannel channel = FileChannel.open(
        Path.of("data.txt"),
        StandardOpenOption.CREATE,
        StandardOpenOption.WRITE,
        StandardOpenOption.TRUNCATE_EXISTING)) {

    ByteBuffer buffer = StandardCharsets.UTF_8.encode("hello nio");
    while (buffer.hasRemaining()) {
        channel.write(buffer);
    }
}

注意 write 不保证一次写完 Buffer 中所有数据,所以要配合 while (buffer.hasRemaining())。

# 3. position

FileChannel 支持获取和设置当前位置。

long position = channel.position();
channel.position(100);

这使它可以实现随机访问文件。

也可以直接从指定位置读取:

channel.read(buffer, 1024);

这种方法不会改变 Channel 当前 position。

# 4. force

force 用于尽量把文件内容刷新到存储设备。

channel.force(true);

参数 true 表示同时刷新文件内容和元数据,false 通常只刷新内容。即便如此,实际语义仍受操作系统和存储设备影响。关键金融类数据要结合事务日志、校验、原子写入等机制设计,不能只依赖一次 force。

# 5. transferTo 和 transferFrom

FileChannel 支持高效数据传输:

try (FileChannel source = FileChannel.open(Path.of("source.dat"), StandardOpenOption.READ);
     FileChannel target = FileChannel.open(Path.of("target.dat"),
             StandardOpenOption.CREATE,
             StandardOpenOption.WRITE,
             StandardOpenOption.TRUNCATE_EXISTING)) {

    long position = 0;
    long size = source.size();
    while (position < size) {
        position += source.transferTo(position, size - position, target);
    }
}

在某些操作系统上,这可以利用零拷贝能力,减少用户态和内核态之间的数据复制。

# 6. SocketChannel

SocketChannel 用于 TCP 客户端连接。

SocketChannel channel = SocketChannel.open();
channel.configureBlocking(false);
channel.connect(new InetSocketAddress("localhost", 8080));

网络 Channel 可以配置为非阻塞模式,并注册到 Selector。

# 7. ServerSocketChannel

ServerSocketChannel 用于 TCP 服务端监听。

ServerSocketChannel server = ServerSocketChannel.open();
server.bind(new InetSocketAddress(8080));
server.configureBlocking(false);

当有新连接到来时,Selector 可以收到 OP_ACCEPT 事件。

# 专家实践清单

Channel 场景 注意点
FileChannel 文件读写、复制、映射 关注 position 和刷盘
SocketChannel TCP 客户端连接 处理半包和半写
ServerSocketChannel 接收连接 非阻塞模式配合 Selector
DatagramChannel UDP 通信 无连接、不保证可靠
AsynchronousFileChannel 异步文件操作 回调和线程池管理

Channel 与 Buffer 的协作:

读:Channel -> Buffer -> 业务解析
写:业务编码 -> Buffer -> Channel

# Tips 快问快答

Q:Channel 是什么? A:NIO 中连接文件、网络等资源的数据通道。

Q:Channel 和 Buffer 谁保存数据? A:Buffer 保存数据,Channel 负责传输。

Q:Channel 是否都是双向的? A:很多 Channel 支持双向,但具体能力取决于实现类型。

Q:FileChannel 能做什么高级操作? A:位置读写、文件映射、强制刷盘、transferTo/transferFrom。

Q:SocketChannel.write 一次一定写完吗? A:不一定,非阻塞模式下可能只写出一部分。

Q:Channel 非阻塞模式有什么要求? A:需要配合 Selector 或事件循环处理就绪事件。

Q:为什么 FileChannel.force 重要? A:它可请求把数据和元数据刷到底层存储,提高崩溃一致性。

Q:Channel 常见错误是什么? A:忽略部分读写、混淆 position、资源未关闭。

# 8. 总结

Channel 是 NIO 的数据通道,Buffer 是数据容器。文件场景中常用 FileChannel 实现随机访问、高效复制、强制刷盘;网络场景中常用 SocketChannel 和 ServerSocketChannel 结合 Selector 实现非阻塞通信。

上次更新: 2026/06/25, 14:19:18
Buffer缓冲区
Selector多路复用

← Buffer缓冲区 Selector多路复用→

Copyright © 2023-2026 Wray | 鄂ICP备2024050235号-1
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式