Netty(二)Netty 与 NIO 之前世今生
package com.lf.io;
import java.nio.IntBuffer;
public class IntBufferDemo {
public static void main(String[] args) {
// 分配新的 int 缓冲区,参数为缓冲区容量
// 新缓冲区的当前位置将为零,其界限(限制位置)将为其容量。它将具有一个底层实现数组,其数组偏移量将为零。
IntBuffer buffer = IntBuffer.allocate(8);
for (int i = 0; i < buffer.capacity(); ++i) {
int j = 2 * (i + 1);
// 将给定整数写入此缓冲区的当前位置,当前位置递增
buffer.put(j);
}
// 重设此缓冲区,将限制设置为当前位置,然后将当前位置设置为 0
buffer.flip();
// 查看在当前位置和限制位置之间是否有元素
while (buffer.hasRemaining()) {
// 读取此缓冲区当前位置的整数,然后当前位置递增
int j = buffer.get();
System.out.print(j + " ");
}
}
}
输出:2 4 6 8 10 12 14 16
package com.lf.io; import java.io.FileInputStream;
import java.nio.Buffer;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel; public class BufferDemo {
public static void main(String args[]) throws Exception {
//这用用的是文件 IO 处理
FileInputStream fin = new FileInputStream("E://test.txt");
//创建文件的操作管道
FileChannel fc = fin.getChannel();
//分配一个 10 个大小缓冲区,说白了就是分配一个 10 个大小的 byte 数组
ByteBuffer buffer = ByteBuffer.allocate(10);
output("初始化", buffer);
//先读一下
fc.read(buffer);
output("调用 read()", buffer);
//准备操作之前,先锁定操作范围
buffer.flip();
output("调用 flip()", buffer);
//判断有没有可读数据
while (buffer.remaining() > 0) {
byte b = buffer.get();
System.out.print(((char) b));
}
output("调用 get()", buffer);
//可以理解为解锁
buffer.clear();
output("调用 clear()", buffer);
//最后把管道关闭
fin.close();
} //把这个缓冲里面实时状态给答应出来
public static void output(String step, Buffer buffer) {
System.out.println(step + " : ");
//容量,数组大小
System.out.print("capacity: " + buffer.capacity() + ", ");
//当前操作数据所在的位置,也可以叫做游标
System.out.print("position: " + buffer.position() + ", ");
//锁定值,flip,数据操作范围索引只能在 position - limit 之间
System.out.println("limit: " + buffer.limit());
System.out.println();
}
}
输出:
初始化 :
capacity: 10, position: 0, limit: 10 调用 read() :
capacity: 10, position: 4, limit: 10 调用 flip() :
capacity: 10, position: 0, limit: 4 LFGB调用 get() :
capacity: 10, position: 4, limit: 4 调用 clear() :
capacity: 10, position: 0, limit: 10 Process finished with exit code 0

/**
* 手动分配缓冲区
*/
public class BufferWrap {
public void myMethod() {
// 分配指定大小的缓冲区
ByteBuffer buffer1 = ByteBuffer.allocate(10);
// 包装一个现有的数组
byte array[] = new byte[10];
ByteBuffer buffer2 = ByteBuffer.wrap(array);
}
}
package com.lf.io; import java.nio.ByteBuffer; /*** 缓冲区分片 */
public class BufferSlice {
static public void main(String args[]) throws Exception {
ByteBuffer buffer = ByteBuffer.allocate(10);
// 缓冲区中的数据 0-9
for (int i = 0; i < buffer.capacity(); ++i) {
buffer.put((byte) i);
}
// 创建子缓冲区
buffer.position(3);
buffer.limit(7);
ByteBuffer slice = buffer.slice();
// 改变子缓冲区的内容
for (int i = 0; i < slice.capacity(); ++i) {
byte b = slice.get(i);
b *= 10;
slice.put(i, b);
}
buffer.position(0);
buffer.limit(buffer.capacity());
while (buffer.remaining() > 0) {
System.out.println(buffer.get());
}
}
}
输出:
0
1
2
30
40
50
60
7
8
9
package com.lf.io;
import java.nio.ByteBuffer;
public class ReadOnlyBuffer {
static public void main(String args[]) throws Exception {
ByteBuffer buffer = ByteBuffer.allocate(10);
// 缓冲区中的数据 0-9
for (int i = 0; i < buffer.capacity(); ++i) {
buffer.put((byte) i);
}
// 创建只读缓冲区
ByteBuffer readonly = buffer.asReadOnlyBuffer();
// 改变原缓冲区的内容
for (int i = 0; i < buffer.capacity(); ++i) {
byte b = buffer.get(i);
b *= 10;
buffer.put(i, b);
}
readonly.position(0);
readonly.limit(buffer.capacity());
// 只读缓冲区的内容也随之改变
while (readonly.remaining() > 0) {
System.out.println(readonly.get());
}
}
}
package com.lf.io; import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel; public class DirectBuffer {
static public void main(String args[]) throws Exception {
//首先我们从磁盘上读取刚才我们写出的文件内容
String infile = "E://test.txt";
FileInputStream fin = new FileInputStream(infile);
FileChannel fcin = fin.getChannel();
//把刚刚读取的内容写入到一个新的文件中
String outfile = String.format("E://testcopy.txt");
FileOutputStream fout = new FileOutputStream(outfile);
FileChannel fcout = fout.getChannel();
// 使用 allocateDirect,而不是 allocate
ByteBuffer buffer = ByteBuffer.allocateDirect(1024);
while (true) {
buffer.clear();
int r = fcin.read(buffer);
if (r == -1) {
break;
}
buffer.flip();
fcout.write(buffer);
}
}
}
package com.lf.io; import java.io.RandomAccessFile;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel; /**
* IO 映射缓冲区
*/
public class MappedBuffer {
static private final int start = 0;
static private final int size = 1024; static public void main(String args[]) throws Exception {
RandomAccessFile raf = new RandomAccessFile("E://test.txt", "rw");
FileChannel fc = raf.getChannel();
//把缓冲区跟文件系统进行一个映射关联
// 只要操作缓冲区里面的内容,文件内容也会跟着改变
MappedByteBuffer mbb = fc.map(FileChannel.MapMode.READ_WRITE, start, size);
mbb.put(0, (byte) 97);
mbb.put(1023, (byte) 122);
raf.close();
}
}
package com.lf.io; import java.io.FileInputStream;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel; public class FileInputDemo {
static public void main(String args[]) throws Exception {
FileInputStream fin = new FileInputStream("E://test.txt");
// 获取通道
FileChannel fc = fin.getChannel();
// 创建缓冲区
ByteBuffer buffer = ByteBuffer.allocate(1024);
// 读取数据到缓冲区
fc.read(buffer);
buffer.flip();
while (buffer.remaining() > 0) {
byte b = buffer.get();
System.out.print(((char) b));
}
fin.close();
}
}
package com.lf.io; import java.io.FileOutputStream;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel; public class FileOutputDemo {
static private final byte message[] = {83, 111, 109, 101, 32, 98, 121, 116, 101, 115, 46}; static public void main(String args[]) throws Exception {
FileOutputStream fout = new FileOutputStream("E://test.txt");
FileChannel fc = fout.getChannel();
ByteBuffer buffer = ByteBuffer.allocate(1024);
for (int i = 0; i < message.length; ++i) {
buffer.put(message[i]);
}
buffer.flip();
fc.write(buffer);
fout.close();
}
}
看看 SelectorProvider.provider()做了什么:



再看看怎么 new PipeImpl()的:




正如这段注释所描述的:




然后通过 serverChannel1.register(selector, SelectionKey.OP_ACCEPT);把 selector 和 channel 绑定在一起,也就是把 new



这个 poll0()会监听 pollWrapper 中的 FD 有没有数据进出,这会造成 IO 阻塞,直到有数据读写事件发生。比如,由于

Netty(二)Netty 与 NIO 之前世今生的更多相关文章
- 2.Netty 与 NIO 之前世今生
2.Netty 与 NIO 之前世今生 本文围绕一下几点阐述: 1. NIO 的核心组件 Buffer.Selector.Channel. 2.何谓多路复用? 3.Netty 支持的功能与特性. ...
- Netty学习笔记(一)——nio基础
Netty简单认识: 1) Netty 是由JBOSS 提供的一个Java 开源框架. 2) Netty 是一个异步的.基于事件驱动的网络应用框架,用以快速开发高性能.高可靠性的网络I0 程序. 3) ...
- Netty学习——Netty和Protobuf的整合(二)
Netty学习——Netty和Protobuf的整合(二) 这程序是有瑕疵的,解码器那里不通用,耦合性太强,有两个很明显的问题,但是要怎么解决呢?如:再加一个内部类型 Person2,之前的代码就不能 ...
- 【Netty】Netty传输
一.前言 在简单学习了Netty中的组件后,接着学习Netty中数据的传输细节. 二.传输 2.1 传输示例 Netty中的数据传输都是使用的字节类型,下面通过一个实例进行说明,该实例中服务器接受请求 ...
- Netty学习——Netty和Protobuf的整合(一)
Netty学习——Netty和Protobuf的整合 Protobuf作为序列化的工具,将序列化后的数据,通过Netty来进行在网络上的传输 1.将proto文件里的java包的位置修改一下,然后再执 ...
- 【Netty】Netty入门之WebSocket小例子
服务端: 引入Netty依赖 <!-- netty --> <dependency> <groupId>io.netty</groupId> <a ...
- 002——Netty之Netty介绍
Netty出现背景 Java NIO难用 据说存在bug 业界其他NIO框架不成熟 Netty主要解决两个相应关注领域 (1)异步和事件驱动的实现. (2)一组设计模式,将应用逻辑与网络层解耦. 特性 ...
- JAVA I/O(二)文件NIO
一.Unix五种I/O模型 读取和写入文件I/O操作都是调用操作系统提高的接口,对磁盘I/O来说,一般是将数据从磁盘拷贝到内核空间,然后从内核空间拷贝到用户空间.为了减小I/O时间,一般内核空间存在高 ...
- 【netty】(1)---BIO NIO AIO演变
BIO NIO AIO演变 Netty是一个提供异步事件驱动的网络应用框架,用以快速开发高性能.高可靠的网络服务器和客户端程序.Netty简化了网络程序的开发,是很多框架和公司都在使用的技术. Net ...
随机推荐
- SQLSERVER 修改数据实例的排序规则
SQL Server服务器修改排序规则的方法 操作及验证步骤: 1 登录数据库后,查看当前安装数据库默认排序规则的两种方式 方式一.使用SQL Server 2014 Management Studi ...
- 前端PDF文件转图片方法
第一步:先下载pdfjs,网址:PDF下载地址,再引入到项目中,我是标签直接引用的 <script src="pdfjs/build/pdf.js"></scri ...
- 前端面试准备笔记之JavaScript(04)
01. DOM的本质 xml是一种可扩展的标记性语言,可扩展就是可以描述任何结构的数据,他是一棵树,可以自定义标签,可以自己扩展. html也是一种特定的xml,他规定了一些标签的名称,结构与xml是 ...
- ACID 原子性(atomicity,或称不可分割性)、一致性(consistency)、隔离性(isolation,又称独立性)、持久性(durability)。
https://en.wikipedia.org/wiki/ACID https://zh.wikipedia.org/wiki/ACID //ACID compliant , row-level l ...
- 深度漫谈数据系统架构——Lambda architecture
https://mp.weixin.qq.com/s/whmhm2yzug2WVdH3dTq8hg
- CSRF Cross-site request forgery 跨站请求伪造
跨站请求伪造目标站---无知用户---恶意站 http://fallensnow-jack.blogspot.com/2011/08/webgoat-csrf.html https://wiki.ca ...
- 作为一款内存数据库,为什么断电后Redis数据不会丢失
前言 Redis 作为一款内存数据库,被广泛使用于缓存,分布式锁等场景,那么假如断电或者因其他因素导致 Reids 服务宕机,在重启之后数据会丢失吗? Redis 持久化机制 Redis 虽然是定义为 ...
- 三:Spring Security 登录添加验证码
Spring Security 登录添加验证码 1.准备验证码 2.自定义过滤器 3.配置 1.准备验证码 要有验证码,首先得先准备好验证码,本文采用 Java 自画的验证码,代码如下: /** * ...
- 十四:SpringBoot-配置MongoDB数据库,实现增删改查逻辑
SpringBoot-配置MongoDB数据库,实现增删改查逻辑 1.MongoDB数据库 1.1 MongoDB简介 1.2 MongoDB特点 2.SpringBoot整合MongoDB 2.1 ...
- Docker是如何实现隔离的
Docker是如何实现隔离的 2.进程的隔离 4.文件的隔离 5.资源的限制 7.与传统虚拟机技术的区别 原文地址: 微信公众号:<鲁智深菜园子>:Docker是如何实现隔离的 # 1.运 ...