NIO-编程实战(一)

简介: NIO-编程实战(一)

一、NIO总共分为三大部分:

1、缓冲区:Buffer是所有的xxxBuffer类的父类,MappedByyteBuffer:映射的类,主要是映射系统中的内存。

缓存区分为两种,一种是直接缓冲区,另一种是非缓冲区。

缓存区有Buffer,ByteBuffer,LongBuffer,IntegerBuffer,FloatBuffer,DoubleBuffer。

非直接缓冲区主要存放在jvm缓存区中来拷贝

直接缓冲区--存在物理内存中。

2、选择器:poll模型是windows里面的,epoll是linux系统中的,select,kqueue是操作系统的整个selector在构建的时候不是由java来构建的,而是由java语言调用c语言来是实现的,它的底层是系统的底层。

3、通道:NIO最关联的就是通道,而通道要和选择器的事件进行绑定。

二、关于Buffer的代码如下:

1、创建ByteBuffer的对象,这里不是new的,而是创建该对象时要分配内存:allocate代表分配一块内存空间,将ByteBuffer的对象指向内存空间里面去。单位是字节,代码如下:

  1. ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
  2. System.out.println("position:"+byteBuffer.position());
  3. System.out.println("limit:"+byteBuffer.limit());
  4. System.out.println("capacity:"+byteBuffer.capacity());
  5. System.out.println("往bytebuffer里存放数据。。。");
  6. byteBuffer.put("A23abc一二三".getBytes());
  7. System.out.println("position:"+byteBuffer.position());
  8. System.out.println("limit:"+byteBuffer.limit());
  9. System.out.println("capacity:"+byteBuffer.capacity());

运行的结果如下:往缓存区里放数据只会导致position的大小会变,其他的不会变。

2、如何从缓存区中读数据

  1. System.out.println("往bytebuffer里读取数据。。。");
  2. byteBuffer.flip();// 开启读取模式
  3. System.out.println("position:"+byteBuffer.position());
  4. System.out.println("limit:"+byteBuffer.limit());
  5. System.out.println("capacity:"+byteBuffer.capacity());
  6. //应用程序的一个缓存
  7. byte[] bytes = new byte[byteBuffer.limit()];
  8. //读取到缓存区中
  9. byteBuffer.get(bytes);
  10. System.out.println(newString(bytes, 0, bytes.length));

运行的结果如下:这时position置为0,limit的值和上次的position的值一样,把position的值赋给limit。一旦缓冲区的容量定下来以后,那么缓冲区的容量是不可变的。读的数据就是从0的位置到15的位置。

3、rewind方法:

  1. System.out.println("往bytebuffer里重复读取数据。。。" );
  2. byteBuffer.rewind();

  3. System.out.println("position:"+byteBuffer.position());
  4. System.out.println("limit:"+byteBuffer.limit());
  5. System.out.println("capacity:"+byteBuffer.capacity());
  6. byte[] bytes2 = new byte[byteBuffer.limit()];
  7. byteBuffer.get(bytes2);
  8. System.out.println(newString(bytes2, 0, bytes.length));

运行的结果如下:rewind:重复读取,不加这个方法会报错,因为limit后面不能再读取数据了。这个方法的意思是重复读的意思。limit不会变,但是position会变为0。

4、clear方法:调用这个方法的意思又可以再进行写的操作。

  1. System.out.println("清空缓存区。。。");
  2. byteBuffer.clear();//// 值不清空 下标清空
  3. System.out.println("position:"+byteBuffer.position());
  4. System.out.println("limit:"+byteBuffer.limit());
  5. System.out.println("capacity:"+byteBuffer.capacity());
  6. System.out.println((char) byteBuffer.get());

运行的结果如下:


小结总结:上面的缓冲区是普通的缓冲区,直接放到了jvm当中的。而缓存区是不停的再读数据,会覆盖。

5、分散读取聚集写入

可以分开去读,写是在一起写。

注意:在分配指定大小的缓冲区的时候,如果是直接缓冲区的话是直接写在内存中,不是写在jvm的工作缓存区的。如果用分散读取聚集写入的话,不能用直接的缓冲区的方式,应该用普通的方式来分配。

代码如下:

  1.        // 随机访问
  2.        RandomAccessFile raf = new RandomAccessFile("d:/abc.txt", "rw");
  3.        // 获取通信
  4.        FileChannel channel = raf.getChannel();
  5.        // 分配指定大小指定缓冲区      

  6.        //这两个缓冲区是连通的
  7.        //buf2相当于是备用缓冲区
  8.        ByteBuffer buf1 = ByteBuffer.allocate(6);
  9.        ByteBuffer buf2 = ByteBuffer.allocate(10);
  10.        // 分散读取
  11.        ByteBuffer[] bufs = {buf1, buf2};
  12.        channel.read(bufs);
  13.        for (ByteBuffer buf : bufs) {
  14.            // 切换成读模式
  15.            buf.flip();
  16.        }
  17.        System.out.println(new String(bufs[0].array(), 0, bufs[0].limit()));
  18.        System.out.println("-----------------------------");
  19.        System.out.println(new String(bufs[1].array(), 0, bufs[1].limit()));
  20.        System.out.println("-----------重复读取-------------");
  21.        RandomAccessFile raf2 = new RandomAccessFile("d:/abc.txt", "rw");
  22.        // 获取通道
  23.        FileChannel channel2 = raf2.getChannel();
  24.        channel2.write(bufs);
  25.        raf2.close();
  26.        raf.close();

运行的结果如下:

关于管道的代码如下:

  1. package com.gerry.nio.demo.nio.channel;

  2. import java.io.*;  
  3. import java.nio.*;  
  4. import java.nio.channels.*;

  5. /**
  6. * 通道和流绑定
  7. * 普通的缓冲区是基于jvm的,直接缓冲区是基于内存的。
  8. */
  9. public class FileInputProgram {  
  10.    static public void main( String args[] ) throws Exception {  
  11.        FileInputStream fin = new FileInputStream("d:/abc.txt");

  12.        // 在jdk1.5之后可以通过文件的流对象获取通道
  13.        FileChannel fc = fin.getChannel();  

  14.        // 创建缓冲区
  15.        ByteBuffer buffer = ByteBuffer.allocate(1024);  

  16.        // 读取数据到缓冲区
  17.        fc.read(buffer);  

  18.        buffer.flip();  
  19.        //判断是否已经读完
  20.        while (buffer.remaining() > 0) {  
  21.            byte b = buffer.get();  
  22.            System.out.print(((char)b));  
  23.        }  

  24.        fin.close();
  25.    }  
  26. }

运行的结果如下:

  1. package com.gerry.nio.demo.nio.channel;

  2. import java.io.*;  
  3. import java.nio.*;  
  4. import java.nio.channels.*;  

  5. public class FileOutputProgram {  
  6.    static private final byte message[] = {'a','c','d','e'};

  7.    static public void main( String args[] ) throws Exception {  
  8.        FileOutputStream fout = new FileOutputStream( "e:/abc.txt");

  9.        FileChannel fc = fout.getChannel();  

  10.        ByteBuffer buffer = ByteBuffer.allocate( 1024 );  

  11.        for (int i=0; i<message.length; ++i) {
  12.            buffer.put(message[i]);
  13.        }
  14.        buffer.flip();
  15.        fc.write( buffer );

  16.        fout.flush();
  17.        fout.close();  
  18.    }  
  19. }

运行的结果如下:

总结:上面的是关于nio的缓冲区和通道中常用的方法做了一个总结,明天继续写关于nio的selector的网络通信的应用以及netty的入门。

相关文章
|
7天前
|
弹性计算 人工智能 架构师
阿里云携手Altair共拓云上工业仿真新机遇
2024年9月12日,「2024 Altair 技术大会杭州站」成功召开,阿里云弹性计算产品运营与生态负责人何川,与Altair中国技术总监赵阳在会上联合发布了最新的“云上CAE一体机”。
阿里云携手Altair共拓云上工业仿真新机遇
|
3天前
|
机器学习/深度学习 算法 大数据
【BetterBench博士】2024 “华为杯”第二十一届中国研究生数学建模竞赛 选题分析
2024“华为杯”数学建模竞赛,对ABCDEF每个题进行详细的分析,涵盖风电场功率优化、WLAN网络吞吐量、磁性元件损耗建模、地理环境问题、高速公路应急车道启用和X射线脉冲星建模等多领域问题,解析了问题类型、专业和技能的需要。
2436 13
【BetterBench博士】2024 “华为杯”第二十一届中国研究生数学建模竞赛 选题分析
|
3天前
|
机器学习/深度学习 算法 数据可视化
【BetterBench博士】2024年中国研究生数学建模竞赛 C题:数据驱动下磁性元件的磁芯损耗建模 问题分析、数学模型、python 代码
2024年中国研究生数学建模竞赛C题聚焦磁性元件磁芯损耗建模。题目背景介绍了电能变换技术的发展与应用,强调磁性元件在功率变换器中的重要性。磁芯损耗受多种因素影响,现有模型难以精确预测。题目要求通过数据分析建立高精度磁芯损耗模型。具体任务包括励磁波形分类、修正斯坦麦茨方程、分析影响因素、构建预测模型及优化设计条件。涉及数据预处理、特征提取、机器学习及优化算法等技术。适合电气、材料、计算机等多个专业学生参与。
1480 14
【BetterBench博士】2024年中国研究生数学建模竞赛 C题:数据驱动下磁性元件的磁芯损耗建模 问题分析、数学模型、python 代码
|
1月前
|
运维 Cloud Native Devops
一线实战:运维人少,我们从 0 到 1 实践 DevOps 和云原生
上海经证科技有限公司为有效推进软件项目管理和开发工作,选择了阿里云云效作为 DevOps 解决方案。通过云效,实现了从 0 开始,到现在近百个微服务、数百条流水线与应用交付的全面覆盖,有效支撑了敏捷开发流程。
19268 29
|
1月前
|
人工智能 自然语言处理 搜索推荐
阿里云Elasticsearch AI搜索实践
本文介绍了阿里云 Elasticsearch 在AI 搜索方面的技术实践与探索。
18816 20
|
1月前
|
Rust Apache 对象存储
Apache Paimon V0.9最新进展
Apache Paimon V0.9 版本即将发布,此版本带来了多项新特性并解决了关键挑战。Paimon自2022年从Flink社区诞生以来迅速成长,已成为Apache顶级项目,并广泛应用于阿里集团内外的多家企业。
17513 13
Apache Paimon V0.9最新进展
|
1月前
|
存储 人工智能 前端开发
AI 网关零代码解决 AI 幻觉问题
本文主要介绍了 AI Agent 的背景,概念,探讨了 AI Agent 网关插件的使用方法,效果以及实现原理。
18695 16
|
5天前
|
编解码 JSON 自然语言处理
通义千问重磅开源Qwen2.5,性能超越Llama
击败Meta,阿里Qwen2.5再登全球开源大模型王座
321 11
|
2天前
|
算法 Java
JAVA并发编程系列(8)CountDownLatch核心原理
面试中的编程题目“模拟拼团”,我们通过使用CountDownLatch来实现多线程条件下的拼团逻辑。此外,深入解析了CountDownLatch的核心原理及其内部实现机制,特别是`await()`方法的具体工作流程。通过详细分析源码与内部结构,帮助读者更好地理解并发编程的关键概念。
|
2天前
|
SQL 监控 druid
Druid连接池学习
Druid学习笔记,使用Druid进行密码加密。参考文档:https://github.com/alibaba/druid
184 80