2、nio的例子实践
下面的例子,说明了,nio中的三大核心类的基本使用。buffer,channel,selector
package com.shengsiyuan.nio; import org.junit.Test; import java.io.*;
import java.net.*;
import java.nio.ByteBuffer;
import java.nio.IntBuffer;
import java.nio.MappedByteBuffer;
import java.nio.channels.*;
import java.nio.channels.spi.SelectorProvider;
import java.security.SecureRandom;
import java.util.Arrays;
import java.util.Iterator;
import java.util.Set; public class NioTest1 { public static void main(String[] args) {
IntBuffer intBuffer = IntBuffer.allocate(10); for (int i = 0; i < intBuffer.capacity(); i++) {
int randomNumber = new SecureRandom().nextInt(20);
intBuffer.put(randomNumber);
} intBuffer.flip();//翻转,从写转到读状态 while (intBuffer.hasRemaining()) {
System.out.println(intBuffer.get());
} } public void testBuffer() {
IntBuffer intBuffer = IntBuffer.allocate(10); for (int i = 0; i < intBuffer.capacity(); i++) {
int randomNumber = new SecureRandom().nextInt(20);
intBuffer.put(randomNumber);
} intBuffer.flip();//翻转,从写转到读状态 while (intBuffer.hasRemaining()) {
System.out.println(intBuffer.get());
}
} /**
* @ClassName: NioTest1
* @Description: 描述 读文件
* @Author:
* @CreateDate: 2019/8/27 21:26
* @Version: 1.0
*/
@Test
public void testChannelRead() {
try {
FileInputStream fileInputStream = new FileInputStream("NioTest1.txt"); FileChannel fileChannel = fileInputStream.getChannel(); ByteBuffer byteBuffer = ByteBuffer.allocate(512); fileChannel.read(byteBuffer); byteBuffer.flip(); while(byteBuffer.remaining() > 0) { byte b = byteBuffer.get();
System.out.println("char is : " + (char) b); if((char)b == 'e') {
byteBuffer.mark();
}
} System.out.println(byteBuffer.position());
System.out.println(byteBuffer.limit());
System.out.println(byteBuffer.capacity()); byteBuffer.reset(); // System.out.println(byteBuffer.mark());
System.out.println(byteBuffer.position());
System.out.println(byteBuffer.limit());
System.out.println(byteBuffer.capacity()); fileChannel.close();
fileInputStream.close(); } catch (Exception e) {
e.printStackTrace();
}
} /**
* @ClassName: NioTest1
* @Description: 描述 写文件
* @Author:
* @CreateDate: 2019/8/27 21:25
* @Version: 1.0
*/
@Test
public void testChannelWrite() {
try{
FileInputStream fileInputStream = new FileInputStream("NioTest1.txt");
FileChannel fileChannel = fileInputStream.getChannel(); FileChannel randowFileChannel = new RandomAccessFile(new File("NioTest1.txt"),"rw").getChannel(); ByteBuffer byteBuffer = ByteBuffer.allocate(512); byte[] byteArr = "hello nio nihao!".getBytes(); byteBuffer.put(byteArr); byteBuffer.flip(); // fileChannel.write(byteBuffer); randowFileChannel.write(byteBuffer);
}catch (Exception e) {
e.printStackTrace();
}
} /**
* @ClassName: NioTest1
* @Description: 描述 读写文件
* @Author:
* @CreateDate: 2019/8/27 21:25
* @Version: 1.0
*/
@Test
public void testChannelReadAndWrite() {
try {
FileInputStream fileInputStream = new FileInputStream("input.txt");
FileOutputStream fileOutputStream = new FileOutputStream("out.txt"); FileChannel inputFileChannel = fileInputStream.getChannel();
FileChannel outputFileChannel = fileOutputStream.getChannel(); ByteBuffer byteBuffer = ByteBuffer.allocate(512); while(inputFileChannel.read(byteBuffer) != -1) { byteBuffer.flip(); outputFileChannel.write(byteBuffer); // byteBuffer.clear();
} }catch (Exception e) {
e.printStackTrace();
} } /**
* @ClassName: NioTest1
* @Description: 描述 切下部分的byteBuffer 作为一个快照,可以实现同步
* @Author:
* @CreateDate: 2019/8/27 21:24
* @Version: 1.0
*/
@Test
public void testSlice() {
try{
ByteBuffer byteBuffer = ByteBuffer.allocate(512); for (int i = 0; i < 20; i++) {
byteBuffer.put((byte)i);
}
// byteBuffer.flip(); ByteBuffer newByteBuffer = byteBuffer.slice(); byteBuffer.put((byte)'a');
byteBuffer.put((byte)'b'); // newByteBuffer.flip();
System.out.println(newByteBuffer.get(0)); // byteBuffer.put(0, (byte)9); newByteBuffer.put(0, (byte)9); System.out.println(byteBuffer.get(20)); System.out.println(newByteBuffer.get(0)); }catch (Exception e) {
e.printStackTrace();
}
} /**
* @ClassName: NioTest1
* @Description: 描述 只读的byteBuffer
* @Author:
* @CreateDate: 2019/8/27 21:24
* @Version: 1.0
*/
@Test
public void testReadonlyBuffer() { ByteBuffer byteBuffer = ByteBuffer.allocate(512);
for (int i = 0; i < 10; i++) {
byteBuffer.put((byte)i);
} ByteBuffer readOnlyBuffer = byteBuffer.asReadOnlyBuffer(); readOnlyBuffer.position(0); readOnlyBuffer.put((byte)1); } /**
* @ClassName: NioTest1
* @Description: 描述 通过直接内存,零拷贝来处理文件
* @Author:
* @CreateDate: 2019/8/27 21:23
* @Version: 1.0
*/
@Test
public void testChannelReadAndWriteDirect() {
try {
FileInputStream fileInputStream = new FileInputStream("input.txt");
FileOutputStream fileOutputStream = new FileOutputStream("out.txt"); FileChannel inputFileChannel = fileInputStream.getChannel();
FileChannel outputFileChannel = fileOutputStream.getChannel(); ByteBuffer byteBuffer = ByteBuffer.allocateDirect(512); while(inputFileChannel.read(byteBuffer) != -1) { byteBuffer.flip(); outputFileChannel.write(byteBuffer); byteBuffer.clear();
} }catch (Exception e) {
e.printStackTrace();
} } /**
* @ClassName: NioTest1 内存映射,来修改文件 而不操作buffer
* @Description: 描述
* @Author:
* @CreateDate: 2019/8/27 21:23
* @Version: 1.0
*/
@Test
public void testMapBuffer() throws Exception {
RandomAccessFile randomAccessFile = new RandomAccessFile("NioTest1.txt", "rw");
FileChannel fileChannel = randomAccessFile.getChannel(); MappedByteBuffer mappedByteBuffer = fileChannel.map(FileChannel.MapMode.READ_WRITE, 0, 5); mappedByteBuffer.put(0, (byte)'a');
mappedByteBuffer.put(3, (byte)'b'); fileChannel.close();
randomAccessFile.close();
} /**
* @ClassName: NioTest1
* @Description: 描述 测试 filelock
* @Author:
* @CreateDate: 2019/8/27 21:30
* @Version: 1.0
*/
@Test
public void testFilelock() throws Exception {
FileChannel fileChannel = new RandomAccessFile("NioTest1.txt", "rw").getChannel(); FileLock fileLock = fileChannel.lock(3, 6, false); System.out.println(fileLock.isValid());
System.out.println(fileLock.isShared());
} /**
* @ClassName: NioTest1
* @Description: 描述
* @Author:
* @CreateDate: 2019/8/27 22:36
* @Version: 1.0
*/
@Test
public void testScattering() throws Exception {
ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
SocketAddress address = new InetSocketAddress(8899);
serverSocketChannel.bind(address); SocketChannel socketChannel = serverSocketChannel.accept(); int messageLength = 2 + 3 +4;
ByteBuffer[] byteBuffers = new ByteBuffer[3]; byteBuffers[0] = ByteBuffer.allocate(2);
byteBuffers[1] = ByteBuffer.allocate(3);
byteBuffers[2] = ByteBuffer.allocate(4); while(true) {
long readLength = 0; //最大读取 messageLength 长度的字符
while(readLength < messageLength ) {
long r = socketChannel.read(byteBuffers);
readLength += r; System.out.println("byteBuffer length r is " + r);
System.out.println("readLength length r is " + readLength); Arrays.asList(byteBuffers).forEach(byteBuffer -> {
System.out.println("p:" + byteBuffer.position() + ", l: " +byteBuffer.limit());
});
} Arrays.asList(byteBuffers).forEach(byteBuffer -> {
byteBuffer.flip();
}); long writeLength = 0;
//写会去
while(writeLength < messageLength) {
long w = socketChannel.write(byteBuffers);
writeLength += w;
System.out.println("byteBuffer length w is " + w);
System.out.println("writeLength length w is " + writeLength); Arrays.asList(byteBuffers).forEach(byteBuffer -> {
System.out.println("p:" + byteBuffer.position() + ", l: " +byteBuffer.limit());
});
} Arrays.asList(byteBuffers).forEach(byteBuffer -> byteBuffer.clear()); }
} @Test
public void testSelector() throws Exception{
Selector selector = Selector.open(); int[] ports = {5000, 5001, 5002, 5003, 5004}; for (int i = 0; i < ports.length; i++) {
ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
serverSocketChannel.configureBlocking(false); //变成非阻塞的模式 很重要 // serverSocketChannel.bind(new InetSocketAddress(ports[i])); ServerSocket serverSocket = serverSocketChannel.socket();
//这个bind 直接绑在 serverSocketChannel 可以不 尝试了下,好像区别不大,都可以走通 但是不能重复绑
serverSocket.bind(new InetSocketAddress(ports[i])); serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT); System.out.println("监听:" + ports[i]);
} while(true) { int number = selector.select();
System.out.println("number:" + number); Set<SelectionKey> selectionKeys = selector.selectedKeys(); Iterator<SelectionKey> keyIterable = selectionKeys.iterator(); System.out.println("selectionKeys : " + selectionKeys); while(keyIterable.hasNext()) {
SelectionKey selectionKey = keyIterable.next();
if(selectionKey.isAcceptable()) {//可接受的
ServerSocketChannel serverSocketChannel = (ServerSocketChannel) selectionKey.channel();
//这里为什么还要调accept 因为上面放进去的就是 ServerSocketChannel ,而且没有调accept 接收请求
SocketChannel socketChannel = serverSocketChannel.accept();
socketChannel.configureBlocking(false); System.out.println("获得链接:" + socketChannel); socketChannel.register(selector, SelectionKey.OP_READ);
// socketChannel.register(selector, SelectionKey.OP_READ); 重复注册好像不影响 keyIterable.remove();//如果不remove selectionKeys中会一直存在事件对象
} else if(selectionKey.isReadable()) {//可读取的
//这里就可以直接用SocketChannel来接收,因为在accept中,是用socketChannel来注册的
SocketChannel socketChannel = (SocketChannel) selectionKey.channel(); ByteBuffer byteBuffer = ByteBuffer.allocate(512);
while(socketChannel.read(byteBuffer) > 0) {
byteBuffer.flip(); System.out.println("读取到客户端的消息:" + byteBuffer);
System.out.println("读取到客户端:" + socketChannel); socketChannel.write(byteBuffer); byteBuffer.clear();
} keyIterable.remove(); } } } }
}
2、nio的例子实践的更多相关文章
- NIO模式例子
NIO模式主要优势是体现在对多连接的管理,对众多连接各种事件的转发让处理变得更加高效,所以一般是服务器端才会使用NIO模式,而对于客户端为了方便及习惯使用阻塞模式的Socket进行通信.所以NIO模式 ...
- IO模型之NIO代码及其实践详解
一.简介 NIO我们一般认为是New I/O(也是官方的叫法),因为它是相对于老的I/O类库新增的( JDK 1.4中的java.nio.*包中引入新的Java I/O库).但现在都称之为Non-bl ...
- docker-1-环境安装及例子实践
1.安装go 先新建一个Go的工作空间文件夹,文件夹路径建议放在$HOME下: userdeMacBook-Pro:~ user$ cd $HOME userdeMacBook-Pro:~ user$ ...
- python argparse例子实践
python 解析命令行读取参数,在多个文件或者不同语言协同的项目中,python脚本经常需要从命令行直接读取参数. 万能的python自带了sys.arg.argparse.optparse模块等, ...
- NIO的学习
参考 http://wenku.baidu.com/link?url=rq-BEp3Et4JRrE62f2Lv9hq8nT_Gq0XPb65h8OBqTAt-ILfqKmdjIhVEp8bctIdm0 ...
- 漫谈Java IO之 NIO那些事儿
前面一篇中已经介绍了基本IO的使用以及最简单的阻塞服务器的例子,本篇就来介绍下NIO的相关内容,前面的分享可以参考目录: 网络IO的基本知识与概念 普通IO以及BIO服务器 NIO的使用与服务器Hel ...
- MapServer Tutorial——MapServer7.2.1教程学习——第一节用例实践:Example1.2 Static Map with Two Layers
MapServer Tutorial——MapServer7.2.1教程学习——第一节用例实践:Example1.2 Static Map with Two Layers 一.前言 上一篇博客< ...
- NIO基本操作
NIO是Java 4里面提供的新的API,目的是用来解决传统IO的问题 NIO主要有三大核心部分:Channel(通道),Buffer(缓冲区), Selector(选择器) Channel(通道) ...
- JAVA NIO non-blocking模式实现高并发服务器(转)
原文链接:JAVA NIO non-blocking模式实现高并发服务器 Java自1.4以后,加入了新IO特性,NIO. 号称new IO. NIO带来了non-blocking特性. 这篇文章主要 ...
随机推荐
- hdu4585Shaolin
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4585 题意: 第一个人ID为1,战斗力为1e9. 给定n,给出n个人的ID和战斗力. 每个人必须和战斗 ...
- BZOJ 2049洞穴探测
辉辉热衷于洞穴勘测.某天,他按照地图来到了一片被标记为JSZX的洞穴群地区.经过初步勘测,辉辉发现这片区域由n个洞穴(分别编号为1到n)以及若干通道组成,并且每条通道连接了恰好两个洞穴.假如两个洞穴可 ...
- Task 的一些个人见解
Task确实比较好用且优雅 我感觉.NET要成为艺术家... public class TheTask { /// <summary> /// 直接调用是同步方法 /// </sum ...
- WebAPI接口的自动化测试2
接口认证: 服务器的接口需要通过一个验证机制,这个验证机制可以是session或token 以session为例. session存储与服务器,通常用户登录后,服务器会把配套的sessionid发送给 ...
- 11个点让你的Spring Boot启动更快
前言 使用的是 OpenJDK 11. java --version openjdk 11.0.1 2018-10-16 OpenJDK Runtime Environment 18.9 (build ...
- C语言每日一练——第5题
一.题目要求 选出大于100小于1000的所有个位数与十位数字之和被10除所得余数恰好是百位数字的所有数字(如293).计算并输出上述这些素数的个数cnt以及这些素数值得sum,最后把结果cnt和su ...
- CSS3新特性简单总结(持续补充常用到的情景)
1.CSS3边框border-radius 左上右下box-shadow box-shadow: 水平阴影(可负值,必) 垂直阴影(可负值,必) 模糊距离 阴影尺寸 颜色颜色 inset(将外部阴影改 ...
- python并发之多进程
#mutiprocessing模块 python中的多线程无法利用多核优势,如果想要充分地使用多核CPU的资源(os.cpu_count()查看),在python中大部分情况需要使用多进程.Pytho ...
- Vue学习笔记:提升开发效率和体验的常用工具
Vetur 用途: 语法高亮 标签补全,模板生成 Lint检查 格式化 vs code环境配置文件 文件-->首选项-->搜索veture(找不到需要自行安装)-->在setting ...
- Spring与Shiro整合 静态注解授权
Spring与Shiro整合 静态注解授权 作者 : Stanley 罗昊 [转载请注明出处和署名,谢谢!] 使用Shiro的种类 首先,Shiro的授权方式共有三种: 1.编程式授权(不推荐) 2. ...