

【对线面试官】Java NIO
source link: https://segmentfault.com/a/1190000038936751
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

服务端:
public class NoBlockServer { public static void main(String[] args) throws IOException { // 1.获取通道 ServerSocketChannel server = ServerSocketChannel.open(); // 2.切换成非阻塞模式 server.configureBlocking(false); // 3. 绑定连接 server.bind(new InetSocketAddress(6666)); // 4. 获取选择器 Selector selector = Selector.open(); // 4.1将通道注册到选择器上,指定接收“监听通道”事件 server.register(selector, SelectionKey.OP_ACCEPT); // 5. 轮训地获取选择器上已“就绪”的事件--->只要select()>0,说明已就绪 while (selector.select() > 0) { // 6. 获取当前选择器所有注册的“选择键”(已就绪的监听事件) Iterator<SelectionKey> iterator = selector.selectedKeys().iterator(); // 7. 获取已“就绪”的事件,(不同的事件做不同的事) while (iterator.hasNext()) { SelectionKey selectionKey = iterator.next(); // 接收事件就绪 if (selectionKey.isAcceptable()) { // 8. 获取客户端的链接 SocketChannel client = server.accept(); // 8.1 切换成非阻塞状态 client.configureBlocking(false); // 8.2 注册到选择器上-->拿到客户端的连接为了读取通道的数据(监听读就绪事件) client.register(selector, SelectionKey.OP_READ); } else if (selectionKey.isReadable()) { // 读事件就绪 // 9. 获取当前选择器读就绪状态的通道 SocketChannel client = (SocketChannel) selectionKey.channel(); // 9.1读取数据 ByteBuffer buffer = ByteBuffer.allocate(1024); // 9.2得到文件通道,将客户端传递过来的图片写到本地项目下(写模式、没有则创建) FileChannel outChannel = FileChannel.open(Paths.get("2.png"), StandardOpenOption.WRITE, StandardOpenOption.CREATE); while (client.read(buffer) > 0) { // 在读之前都要切换成读模式 buffer.flip(); outChannel.write(buffer); // 读完切换成写模式,能让管道继续读取文件的数据 buffer.clear(); } } // 10. 取消选择键(已经处理过的事件,就应该取消掉了) iterator.remove(); } } } }
客户端:
public class NoBlockClient { public static void main(String[] args) throws IOException { // 1. 获取通道 SocketChannel socketChannel = SocketChannel.open(new InetSocketAddress("127.0.0.1", 6666)); // 1.1切换成非阻塞模式 socketChannel.configureBlocking(false); // 1.2获取选择器 Selector selector = Selector.open(); // 1.3将通道注册到选择器中,获取服务端返回的数据 socketChannel.register(selector, SelectionKey.OP_READ); // 2. 发送一张图片给服务端吧 FileChannel fileChannel = FileChannel.open(Paths.get("X:\\Users\\ozc\\Desktop\\面试造火箭\\1.png"), StandardOpenOption.READ); // 3.要使用NIO,有了Channel,就必然要有Buffer,Buffer是与数据打交道的呢 ByteBuffer buffer = ByteBuffer.allocate(1024); // 4.读取本地文件(图片),发送到服务器 while (fileChannel.read(buffer) != -1) { // 在读之前都要切换成读模式 buffer.flip(); socketChannel.write(buffer); // 读完切换成写模式,能让管道继续读取文件的数据 buffer.clear(); } // 5. 轮训地获取选择器上已“就绪”的事件--->只要select()>0,说明已就绪 while (selector.select() > 0) { // 6. 获取当前选择器所有注册的“选择键”(已就绪的监听事件) Iterator<SelectionKey> iterator = selector.selectedKeys().iterator(); // 7. 获取已“就绪”的事件,(不同的事件做不同的事) while (iterator.hasNext()) { SelectionKey selectionKey = iterator.next(); // 8. 读事件就绪 if (selectionKey.isReadable()) { // 8.1得到对应的通道 SocketChannel channel = (SocketChannel) selectionKey.channel(); ByteBuffer responseBuffer = ByteBuffer.allocate(1024); // 9. 知道服务端要返回响应的数据给客户端,客户端在这里接收 int readBytes = channel.read(responseBuffer); if (readBytes > 0) { // 切换读模式 responseBuffer.flip(); System.out.println(new String(responseBuffer.array(), 0, readBytes)); } } // 10. 取消选择键(已经处理过的事件,就应该取消掉了) iterator.remove(); } } } }
文章以纯面试的角度去讲解,所以有很多的细节是未铺垫的。
鉴于很多同学反馈没看懂【 对线面试官 】系列,基础相关的知识我确实写过文章讲解过啦,但有的同学就是不爱去翻。
为了让大家有更好的体验,我把基础文章也找出来(重要的知识点我还整理过 电子书 ,比如说像多线程、集合这种面试必考的早就已经转成PDF格式啦)
我把这些 上传到网盘 ,你们有需要直接下载就好了。做到这份上了, 不会还想白嫖吧 ? 点赞 和 转发 又不用钱。
链接: https://pan.baidu.com/s/1pQTuKBYsHLsUR5ORRAnwFg 密码:3wom
欢迎关注我的微信公众号【 Java3y 】来聊聊Java面试
Recommend
-
156
Delve into the world of Java NIO Programming with this compact cookbook that introduces common recipes for the Java NIO operations! Java.nio (NIO stands for non-blocking I/O) is a collection of Java programming language APIs that offer features...
-
61
也许很多朋友在学习NIO的时候都会感觉有点吃力,对里面的很多概念都感觉不是那么明朗。在进入Java NIO编程之前,我们今天先来讨论一些比较基础的知识:I/O模型。下面本文先从同步和异步的概念 说起,然后接着阐述了阻塞和非阻塞的区别,...
-
21
最近打算把Java网络编程相关的知识深入一下(IO、NIO、Socket编程、Netty) Java NIO主要需要理解缓冲区、通道、选择器三个核心概念,作为对Java I/O的补充, 以提升大批量数据传输的效率。 学习NIO之前最好能有基础的网络...
-
16
【Java】NIO的原理与浅析 用户空间与内核空间现在操作系统都是采用虚拟存储器,那么对32位操作系统而言,它的寻址空间(虚拟存储空间)为4G(2的32次方)。操作系统的核心是内核,独立于普通的应用程序,可以访问受保...
-
18
FileChannel 提供了一种通过通道来访问文件的方式,它可以通过带参数 position(int) 方法定位到文件的任意位置开始进行操作,还能够将文件映射到直接内存,提高大文件的访问效率。本文将介绍其详细用法和原理。 1. 通道获取...
-
11
选择器 Selector 是 I/O 多路复用的核心组件,它可以监控实现了 SelectableChannel 的 通道 的就绪情况。有了多路复用(multiplexing) I/O 模型,使得单线程的 Java 程序...
-
8
java的IO与NIO 发表于 2021-07-04 ...
-
9
引言 缓冲区是一个用于特定基本类型的容器。由java.nio 包定义,所有缓冲区都是 Buffer 抽象类的子类。
-
7
面试官:什么是NIO?NIO的原理是什么? NIO和IO到底有什么区别?有什么关系? 首先说一下核心区别:...
-
7
大家好,欢迎来到Tlog4J课堂,我是Jensen。我相信有不少同学在IO多路复用这一块跪过,那今天我们还是以面试的方式,听听阿里的P7的大牛“赵总”给大家上NIO这一课。下面咱们直接进入面试场景——ACTION面试官:简单说一下BI...
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK