java.nio 包详解

java.nio(New I/O)是 Java 1.4 引入的高性能 I/O API,提供了比传统 java.io 更高效的 I/O 操作方式,特别适合处理大量数据和高并发场景。


核心组件

1. 缓冲区(Buffers)

核心类:

  • ByteBuffer、CharBuffer、ShortBuffer、IntBuffer、LongBuffer、FloatBuffer、DoubleBuffer

  • MappedByteBuffer(内存映射文件缓冲区)

基本用法:

java 复制代码
// 创建缓冲区
ByteBuffer buffer = ByteBuffer.allocate(1024);  // 堆缓冲区
ByteBuffer directBuffer = ByteBuffer.allocateDirect(1024);  // 直接缓冲区

// 写入数据
buffer.put((byte)1);
buffer.putInt(123);
buffer.putDouble(3.14);

// 切换为读模式
buffer.flip();

// 读取数据
byte b = buffer.get();
int i = buffer.getInt();
double d = buffer.getDouble();

// 清空缓冲区
buffer.clear();

缓冲区状态属性:

  • capacity:缓冲区容量

  • position:当前位置

  • limit:读写限制

  • mark:标记位置

2. 通道(Channels)

核心通道类:

  • FileChannel:文件通道

  • SocketChannel、ServerSocketChannel:TCP 通道

  • DatagramChannel:UDP 通道

  • Pipe.SinkChannel、Pipe.SourceChannel:管道通道

文件通道示例:

java 复制代码
// 文件读取
try (FileChannel channel = FileChannel.open(Paths.get("file.txt"), StandardOpenOption.READ)) {
    ByteBuffer buffer = ByteBuffer.allocate(1024);
    while (channel.read(buffer) > 0) {
        buffer.flip();
        // 处理数据
        buffer.clear();
    }
}

// 文件写入
try (FileChannel channel = FileChannel.open(Paths.get("file.txt"), 
        StandardOpenOption.WRITE, StandardOpenOption.CREATE)) {
    ByteBuffer buffer = ByteBuffer.wrap("Hello NIO".getBytes());
    channel.write(buffer);
}

3. 选择器(Selectors)

用于非阻塞 I/O 的多路复用:

java 复制代码
Selector selector = Selector.open();
ServerSocketChannel serverChannel = ServerSocketChannel.open();
serverChannel.configureBlocking(false);
serverChannel.bind(new InetSocketAddress(8080));
serverChannel.register(selector, SelectionKey.OP_ACCEPT);

while (true) {
    selector.select();
    Set<SelectionKey> selectedKeys = selector.selectedKeys();
    Iterator<SelectionKey> iter = selectedKeys.iterator();
    
    while (iter.hasNext()) {
        SelectionKey key = iter.next();
        
        if (key.isAcceptable()) {
            // 处理新连接
            SocketChannel client = serverChannel.accept();
            client.configureBlocking(false);
            client.register(selector, SelectionKey.OP_READ);
        } else if (key.isReadable()) {
            // 处理读取
            SocketChannel client = (SocketChannel) key.channel();
            ByteBuffer buffer = ByteBuffer.allocate(1024);
            client.read(buffer);
            // 处理数据
        }
        iter.remove();
    }
}

高级特性

1. 内存映射文件(Memory-Mapped Files)

java 复制代码
try (FileChannel channel = FileChannel.open(Paths.get("largefile.dat"), 
        StandardOpenOption.READ)) {
    MappedByteBuffer mappedBuffer = channel.map(
        FileChannel.MapMode.READ_ONLY, 0, channel.size());
    
    // 直接操作内存映射区域
    while (mappedBuffer.hasRemaining()) {
        byte b = mappedBuffer.get();
    }
}

2. 文件锁定

java 复制代码
try (FileChannel channel = FileChannel.open(Paths.get("file.txt"), 
        StandardOpenOption.WRITE)) {
    // 排他锁
    FileLock lock = channel.lock();
    try {
        // 执行写操作
        channel.write(ByteBuffer.wrap("Data".getBytes()));
    } finally {
        lock.release();
    }
    
    // 共享锁(只读)
    FileLock sharedLock = channel.lock(0, Long.MAX_VALUE, true);
}

3. 分散/聚集 I/O(Scatter/Gather)

java 复制代码
// 分散读取
ByteBuffer header = ByteBuffer.allocate(128);
ByteBuffer body = ByteBuffer.allocate(1024);
ByteBuffer[] buffers = {header, body};
channel.read(buffers);

// 聚集写入
header.flip();
body.flip();
channel.write(buffers);

4. 文件系统操作

java.nio.file 包(NIO.2,Java 7 引入)提供了更强大的文件系统操作:

java 复制代码
Path path = Paths.get("/path/to/file");
Files.createDirectories(path.getParent());
Files.write(path, "content".getBytes(), StandardOpenOption.CREATE);

// 遍历目录
try (Stream<Path> stream = Files.list(Paths.get("/tmp"))) {
    stream.forEach(System.out::println);
}

// 文件监控
WatchService watcher = FileSystems.getDefault().newWatchService();
Path dir = Paths.get("/path/to/watch");
dir.register(watcher, 
    StandardWatchEventKinds.ENTRY_CREATE,
    StandardWatchEventKinds.ENTRY_DELETE,
    StandardWatchEventKinds.ENTRY_MODIFY);

性能优势

  1. 非阻塞 I/O:允许单线程管理多个通道

  2. 内存映射:直接操作文件内存映射,避免系统调用

  3. 直接缓冲区:减少 JVM 堆与本地内存间的数据拷贝

  4. 零拷贝 :通过 FileChannel.transferTo/transferFrom 实现

与传统 I/O 对比

特性 java.io java.nio
数据流 流式 基于缓冲区
阻塞模式 阻塞 可选非阻塞
多连接处理 每个连接一个线程 单线程多路复用
性能 适合少量连接 适合高并发
API 复杂度 简单 较复杂

最佳实践

  1. 大文件处理:优先使用内存映射文件

  2. 高并发网络:使用 Selector 实现非阻塞 I/O

  3. 频繁 I/O 操作:使用直接缓冲区减少拷贝

  4. 资源释放:确保关闭通道和选择器

  5. 异常处理 :妥善处理 IOException 和 ClosedChannelException


总结

java.nio 包提供了:

  • 基于缓冲区的 I/O 操作

  • 非阻塞 I/O 支持

  • 内存映射文件功能

  • 高效的文件和网络操作

  • 更灵活的文件系统接口(NIO.2)

虽然学习曲线比传统 I/O 更陡峭,但在处理高性能 I/O 需求时,NIO 通常是更好的选择。对于简单文件操作,可以结合使用 java.nio.file 包提供的便捷方法。

相关推荐
承渊政道1 小时前
【从零开始大模型开发与微调:基于PyTorch与ChatGLM】(开源大模型ChatGLM高级定制化应用实战)
人工智能·pytorch·python·llm·模型微调·glm
Joy T2 小时前
Agent 确定性上下文设计:从 Prompt 参数注入到能力分层
java·开发语言·微服务·架构·prompt·agent context
m0_587383005 小时前
广州 24 小时自助健身房解决方案技术实现与实战指南
java·spring·小程序·架构·需求分析
·云扬·6 小时前
Prompt 工程与安全:从 System 设计到注入防御
java·人工智能·安全·ai·prompt
代码不停7 小时前
自动化测试(java)
java·开发语言·selenium·自动化
Smoothcloud润云7 小时前
PyTorch大模型权重加载与启动耗时优化实战:定位磁盘、内存与显存瓶颈
人工智能·pytorch·python·深度学习·gpu算力
databook7 小时前
从循环到向量化:NumPy提速的7个关键思维
python·数据分析·numpy
棉猴8 小时前
玩游戏学Python1-Python和pgzero库的安装
python·pygame·玩游戏·pgzero·pgzrun
诺伦8 小时前
GEO优化数据实证:78%引用流向官网的机制拆解与小品牌三步管线实战教程 | RiseClaw玄策
python·seo·geo·内容营销·ai搜索
oooost8 小时前
pytorch学习笔记1
python·学习方法