Netty入门到超神系列-Java NIO零拷贝实战

简介: 这一章我们来操作一下NIO的零拷贝,这里我会先写代码样式一下传统IO数据拷贝场景下的耗时,然后再对比NIO场景下的考别耗时,通过耗时差异就能看到NIO零拷贝和传统IO拷贝的区别了。

前言

这一章我们来操作一下NIO的零拷贝,这里我会先写代码样式一下传统IO数据拷贝场景下的耗时,然后再对比NIO场景下的考别耗时,通过耗时差异就能看到NIO零拷贝和传统IO拷贝的区别了。

传统IO拷贝

服务端

服务端主要是接收一下客户端传输过来的数据

//普通拷贝 - 服务端publicclassSocketServer {
publicstaticvoidmain(String[] args) throwsException {
//创建ServerSocketServerSocketserverSocket=newServerSocket(5000);
while(true){
//接待请求Socketsocket=serverSocket.accept();
//获取输入流DataInputStreamdataInputStream=newDataInputStream(socket.getInputStream());
//读取数据byte[] bytes=newbyte[1024];
intsize=0;
while(true){
try{
size=dataInputStream.read(bytes,0,bytes.length);
if(size==-1)break;
//读数据                }catch (Exceptione){
e.printStackTrace();
                }
            }
        }
    }
}

客户端

客户端我们从磁盘读取一个文件,然后通过socket进行网络传输,并记录下消耗的时间

publicclassSocketClient {
publicstaticvoidmain(String[] args) throwsException {
//创建SocketSocketsocket=newSocket("127.0.0.1",5000);
//文件输入流FileInputStreamfileInputStream=newFileInputStream("D:\\idea-space\\idea-code\\netty-demo\\src\\main\\java\\cn\\itsource\\nio\\zerocopy\\img.zip");
//输出流OutputStreamoutputStream=socket.getOutputStream();
byte[] bytes=newbyte[10240];
intsize=0 ;
inttotal=0;
longstart=System.currentTimeMillis();
//把文件中的数据写到socketwhile((size=fileInputStream.read(bytes)) !=-1){
total+=size;
outputStream.write(bytes);
        }
//发送:1813047字节,耗时:16System.out.println("发送:"+total+"字节,耗时:"+(System.currentTimeMillis() -start));
outputStream.close();
fileInputStream.close();
socket.close();
    }
}

我这里 发送:1813047字节,耗时:16

Java NIO拷贝

NIO拷贝要的事情和上面是一样的,只是代码有些差别

服务端

publicclassNIOCopyServer {
publicstaticvoidmain(String[] args) throwsIOException {
//服务端ServerSocketChannelserverSocketChannel=ServerSocketChannel.open();
//监听serverSocketChannel.bind(newInetSocketAddress("127.0.0.1",6000));
//缓冲区ByteBufferbyteBuffer=ByteBuffer.allocate(1024);
while (true){
SocketChannelsocketChannel=serverSocketChannel.accept();
while(true){
if(-1!=socketChannel.read(byteBuffer)){
break;
                }
//为了重复利用buffer,考完一次就清空byteBuffer.clear();
            }
        }
    }
}

客户端

JAVA中的NIO零拷贝可以通过 fileChannel.transferTo 方法来实现 ,具体代码如下

publicclassNIOCopyClient {
publicstaticvoidmain(String[] args) throwsIOException {
//创建通道SocketChannelsocketChannel=SocketChannel.open();
//链接服务端socketChannel.connect(newInetSocketAddress("127.0.0.1",6000));
//文件输入流FileInputStreamfileInputStream=newFileInputStream("D:\\idea-space\\idea-code\\netty-demo\\src\\main\\java\\cn\\itsource\\nio\\zerocopy\\img.zip");
//读文件的通道FileChannelfileChannel=fileInputStream.getChannel();
longstart=System.currentTimeMillis();
//transferTo 方法使用到了零拷贝技术//注意:在window上该方法一次只是支持8m数据拷贝,如果数据比价大,需要切片后多次传输longtotal=fileChannel.transferTo(0, fileChannel.size(), socketChannel);
//发送字节数:1813047 ,耗时:4System.out.println("发送字节数:"+total+" ,耗时:"+(System.currentTimeMillis() -start));
fileInputStream.close();
fileChannel.close();
socketChannel.close();
    }
}

同样的文件,同样的大小,发送字节数:1813047 , NIO 耗时:4 ,而传统IO拷贝 16,我这里文件2M不到,如果文件再大一点,效果更加明显。

文章到这就结束了,这一章比较简单,只是一个小案例,凑个篇数。当然点赞还是要求一下的,万一屏幕面前的大帅哥,或者大漂亮一不小心就一键三连了啦,那我就是熬夜到头发掉光,也出下章

目录
相关文章
|
9天前
|
存储 Java 开发者
Java Map实战:用HashMap和TreeMap轻松解决复杂数据结构问题!
【10月更文挑战第17天】本文深入探讨了Java中HashMap和TreeMap两种Map类型的特性和应用场景。HashMap基于哈希表实现,支持高效的数据操作且允许键值为null;TreeMap基于红黑树实现,支持自然排序或自定义排序,确保元素有序。文章通过具体示例展示了两者的实战应用,帮助开发者根据实际需求选择合适的数据结构,提高开发效率。
32 2
|
14天前
|
存储 消息中间件 安全
JUC组件实战:实现RRPC(Java与硬件通过MQTT的同步通信)
【10月更文挑战第9天】本文介绍了如何利用JUC组件实现Java服务与硬件通过MQTT的同步通信(RRPC)。通过模拟MQTT通信流程,使用`LinkedBlockingQueue`作为消息队列,详细讲解了消息发送、接收及响应的同步处理机制,包括任务超时处理和内存泄漏的预防措施。文中还提供了具体的类设计和方法实现,帮助理解同步通信的内部工作原理。
JUC组件实战:实现RRPC(Java与硬件通过MQTT的同步通信)
|
11天前
|
开发框架 Java 程序员
揭开Java反射的神秘面纱:从原理到实战应用!
本文介绍了Java反射的基本概念、原理及应用场景。反射允许程序在运行时动态获取类的信息并操作其属性和方法,广泛应用于开发框架、动态代理和自定义注解等领域。通过反射,可以实现更灵活的代码设计,但也需注意其性能开销。
29 1
|
17天前
|
Java
让星星⭐月亮告诉你,Java NIO之Buffer详解 属性capacity/position/limit/mark 方法put(X)/get()/flip()/compact()/clear()
这段代码演示了Java NIO中`ByteBuffer`的基本操作,包括分配、写入、翻转、读取、压缩和清空缓冲区。通过示例展示了`position`、`limit`和`mark`属性的变化过程,帮助理解缓冲区的工作原理。
21 2
|
2月前
|
存储 网络协议 Java
Java NIO 开发
本文介绍了Java NIO(New IO)及其主要组件,包括Channel、Buffer和Selector,并对比了NIO与传统IO的优势。文章详细讲解了FileChannel、SocketChannel、ServerSocketChannel、DatagramChannel及Pipe.SinkChannel和Pipe.SourceChannel等Channel实现类,并提供了示例代码。通过这些示例,读者可以了解如何使用不同类型的通道进行数据读写操作。
Java NIO 开发
|
2月前
|
缓存 负载均衡 Dubbo
Dubbo技术深度解析及其在Java中的实战应用
Dubbo是一款由阿里巴巴开源的高性能、轻量级的Java分布式服务框架,它致力于提供高性能和透明化的RPC远程服务调用方案,以及SOA服务治理方案。
66 6
|
2月前
|
Java
领略Lock接口的风采,通过实战演练,让你迅速掌握这门高深武艺,成为Java多线程领域的武林盟主
领略Lock接口的风采,通过实战演练,让你迅速掌握这门高深武艺,成为Java多线程领域的武林盟主
32 7
|
2月前
|
Java
Java-FileInputStream和FileOutputStream的使用,txt文件及图片文件的拷贝
这篇文章介绍了Java中FileInputStream和FileOutputStream的使用,包括如何读取和写入txt文件以及如何拷贝图片文件。
Java-FileInputStream和FileOutputStream的使用,txt文件及图片文件的拷贝
|
2月前
|
Java Android开发 C++
🚀Android NDK开发实战!Java与C++混合编程,打造极致性能体验!📊
在Android应用开发中,追求卓越性能是不变的主题。本文介绍如何利用Android NDK(Native Development Kit)结合Java与C++进行混合编程,提升应用性能。从环境搭建到JNI接口设计,再到实战示例,全面展示NDK的优势与应用技巧,助你打造高性能应用。通过具体案例,如计算斐波那契数列,详细讲解Java与C++的协作流程,帮助开发者掌握NDK开发精髓,实现高效计算与硬件交互。
98 1
|
2月前
|
Java 数据中心 微服务
Java高级知识:线程池隔离与信号量隔离的实战应用
在Java并发编程中,线程池隔离与信号量隔离是两种常用的资源隔离技术,它们在提高系统稳定性、防止系统过载方面发挥着重要作用。
24 0