前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Carson带你学Java:全面 & 清晰的 NIO 学习攻略

Carson带你学Java:全面 & 清晰的 NIO 学习攻略

作者头像
Carson.Ho
发布2022-03-25 14:47:43
2470
发布2022-03-25 14:47:43
举报
文章被收录于专栏:Android知识分享Android知识分享

前言

  • JDK 1.4后,Java提供了一个全新的IO API,即 Java New IO
  • 本文 全面 & 详细解析Java New IO,希望你们会喜欢

目录

示意图
示意图

储备知识:Java IO

示意图
示意图

1. 定义

  • Java New IO
  • 是1个全新的、 JDK 1.4后提供的 IO API

2. 作用

  • 提供了与标准IO不同的IO工作方式
  • 可替代 标准Java IOIO API

3. 新特性

对比于 Java IONIO具备的新特性如下

示意图
示意图

4. 核心组件

Java NIO的核心组件 包括:

  • 通道(Channel
  • 缓冲区(Buffer
  • 选择器(Selectors

下面将详细介绍:

示意图
示意图

5. 具体使用

5.1 基于通道 & 缓冲数据

具体步骤如下:

代码语言:javascript
复制
    // 1. 获取数据源 和 目标传输地的输入输出流(此处以数据源 = 文件为例)
    FileInputStream fin = new FileInputStream(infile);
    FileOutputStream fout = new FileOutputStream(outfile);

    // 2. 获取数据源的输入输出通道
    FileChannel fcin = fin.getChannel();
    FileChannel fcout = fout.getChannel();

    // 3. 创建 缓冲区 对象:Buffer(共有2种方法)
     // 方法1:使用allocate()静态方法
     ByteBuffer buff = ByteBuffer.allocate(256);
     // 上述方法创建1个容量为256字节的ByteBuffer
     // 注:若发现创建的缓冲区容量太小,则重新创建一个大小合适的缓冲区

    // 方法2:通过包装一个已有的数组来创建
     // 注:通过包装的方法创建的缓冲区保留了被包装数组内保存的数据
     ByteBuffer buff = ByteBuffer.wrap(byteArray);

     // 额外:若需将1个字符串存入ByteBuffer,则如下
     String sendString="你好,服务器. ";
     ByteBuffer sendBuff = ByteBuffer.wrap(sendString.getBytes("UTF-16"));

    // 4. 从通道读取数据 & 写入到缓冲区
    // 注:若 以读取到该通道数据的末尾,则返回-1
    fcin.read(buff);

    // 5. 传出数据准备:将缓存区的写模式 转换->> 读模式
    buff.flip();

    // 6. 从 Buffer 中读取数据 & 传出数据到通道
    fcout.write(buff);

    // 7. 重置缓冲区
    // 目的:重用现在的缓冲区,即 不必为了每次读写都创建新的缓冲区,在再次读取之前要重置缓冲区
    // 注:不会改变缓冲区的数据,只是重置缓冲区的主要索引值
    buff.clear();

5.2 基于选择器(Selecter)

具体步骤如下:

代码语言:javascript
复制
// 1. 创建Selector对象   
Selector sel = Selector.open();

// 2. 向Selector对象绑定通道   
 // a. 创建可选择通道,并配置为非阻塞模式   
 ServerSocketChannel server = ServerSocketChannel.open();   
 server.configureBlocking(false);   
 
 // b. 绑定通道到指定端口   
 ServerSocket socket = server.socket();   
 InetSocketAddress address = new InetSocketAddress(port);   
 socket.bind(address);   
 
 // c. 向Selector中注册感兴趣的事件   
 server.register(sel, SelectionKey.OP_ACCEPT);    
 return sel;

// 3. 处理事件
try {    
    while(true) { 
        // 该调用会阻塞,直到至少有一个事件就绪、准备发生 
        selector.select(); 
        // 一旦上述方法返回,线程就可以处理这些事件
        Set<SelectionKey> keys = selector.selectedKeys(); 
        Iterator<SelectionKey> iter = keys.iterator(); 
        while (iter.hasNext()) { 
            SelectionKey key = (SelectionKey) iter.next(); 
            iter.remove(); 
            process(key); 
        }    
    }    
} catch (IOException e) {    
    e.printStackTrace();   
}

6. 实例讲解

  • 实例说明:实现文件复制功能
  • 实现方式:通道FileChannel、 缓冲区ByteBuffer
代码语言:javascript
复制
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;

public class Test {

    public static void main(String[] args) throws IOException {
        // 设置输入源 & 输出地 = 文件
        String infile = "C:\\copy.sql";
        String outfile = "C:\\copy.txt";

        // 1. 获取数据源 和 目标传输地的输入输出流(此处以数据源 = 文件为例)
        FileInputStream fin = new FileInputStream(infile);
        FileOutputStream fout = new FileOutputStream(outfile);

        // 2. 获取数据源的输入输出通道
        FileChannel fcin = fin.getChannel();
        FileChannel fcout = fout.getChannel();

        // 3. 创建缓冲区对象
        ByteBuffer buff = ByteBuffer.allocate(1024);
        
        while (true) {

            // 4. 从通道读取数据 & 写入到缓冲区
            // 注:若 以读取到该通道数据的末尾,则返回-1  
            int r = fcin.read(buff);
            if (r == -1) {
                break;
            }
            // 5. 传出数据准备:调用flip()方法  
            buff.flip();
            
            // 6. 从 Buffer 中读取数据 & 传出数据到通道
            fcout.write(buff);
            
            // 7. 重置缓冲区
            buff.clear();
            
          }
        }

}

7. 与Java IO的区别

示意图
示意图

8. 总结

  • 本文全面讲解了Java中的NIO的相关知识
  • 下面我将继续对 Android & Java中的知识进行深入讲解
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • 目录
  • 储备知识:Java IO
  • 1. 定义
  • 2. 作用
  • 3. 新特性
  • 4. 核心组件
  • 5. 具体使用
    • 5.1 基于通道 & 缓冲数据
      • 5.2 基于选择器(Selecter)
      • 6. 实例讲解
      • 7. 与Java IO的区别
      • 8. 总结
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档