java nio之 channel通道
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java nio之 channel通道相关的知识,希望对你有一定的参考价值。
java nio 通道上一篇文章里就讲述过,channel总是写数据的时候,要先把数据写入到bytebuffer,读数据的时候总是要先从channel中读入到bytebuffer。如下图,这个图是好多知名博客常用的图,很好理解这个channel。
channel分为一下几种:
FileChannel
SocketChannel
ServerSocketChannel
DatagramChannel
FileChannel:
经常说的FileChannel都是拿下面的例子说事
代码如下:
package com.nio.basic; import java.io.IOException; import java.io.RandomAccessFile; /** * Created by sdc on 2017/8/13. */ public class RandomAccessFileTest { public static void main(String[] args) { readFile(); } /** * 读取文件 * @throws Exception */ public static void readFile(){ String fileName = "C:\\Users\\sdc\\Desktop\\gc (2).log"; RandomAccessFile randomAccessFile = null; try{ randomAccessFile = new RandomAccessFile(fileName, "r"); long fileLength = randomAccessFile.length(); System.out.print("length" + fileLength); int start = 100; randomAccessFile.seek(start); byte[] bytes = new byte[20]; int read = 0; while ((read = randomAccessFile.read(bytes)) != -1) { System.out.println(new String(bytes, "UTF-8")); } System.out.println(bytes.length); System.out.println(new String(bytes, "UTF-8")); }catch (Exception e) { e.printStackTrace(); }finally { if (randomAccessFile != null) { try { randomAccessFile.close(); } catch (IOException e) { e.printStackTrace(); } } } } }
还有这样的例子:
FileInputStream is = new FileInputStream(new File(src)); FileChannel channelFrom = is.getChannel();
其实这两个是用到了nio的channel,不妨自己写一个例子试试。
SocketChannel和ServerSocketChannel一般是两个集合起来说的,一个用于客户端连接,一个用于服务端连接。
package com.nio.basic; import java.io.IOException; import java.net.InetSocketAddress; import java.nio.ByteBuffer; import java.nio.channels.SelectionKey; import java.nio.channels.Selector; import java.nio.channels.ServerSocketChannel; import java.nio.channels.SocketChannel; import java.util.Iterator; import java.util.Set; /** * nio 服务端 * Created by sdc on 2017/8/13. */ public class Nioserver { ByteBuffer buffer = ByteBuffer.allocate(1024); public static void main(String[] args) throws IOException { System.out.println("server started..."); try { new NIoServer().run(); } catch (Exception e) { e.printStackTrace(); } } public void run () throws Exception { //打开服务器端的套接字通道 ServerSocketChannel serverSocketChannel = ServerSocketChannel.open(); //服务器端设置为非阻塞 serverSocketChannel.configureBlocking(false); //服务端进行绑定 serverSocketChannel.bind(new InetSocketAddress("localhost", 8000)); //注册感兴趣的事件 Selector selector = Selector.open(); serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT); while (true) { int selectCount = selector.select(); if( selectCount ==0 ) { continue; } selector.select(); Set<SelectionKey> keys = selector.selectedKeys(); //获取迭代器 Iterator<SelectionKey> keyIterator = keys.iterator(); while (keyIterator.hasNext()) { SelectionKey key = keyIterator.next(); if (!key.isValid()) { continue; } if (key.isAcceptable()) { ServerSocketChannel sscTemp = (ServerSocketChannel) key.channel(); //得到一个连接好的SocketChannel,并把它注册到Selector上,兴趣操作为READ SocketChannel socketChannel = sscTemp.accept(); socketChannel.configureBlocking(false); socketChannel.register(selector, SelectionKey.OP_READ); System.out.println("REGISTER CHANNEL , CHANNEL NUMBER IS:" + selector.keys().size()); } else if (key.isReadable()) { //读取通道中的数据 SocketChannel channel = (SocketChannel) key.channel(); read(channel); } keyIterator.remove(); //该事件已经处理,可以丢弃 } } } private void read(SocketChannel channel) throws IOException { int count ; buffer.clear(); try { while ((count = channel.read(buffer)) > 0) { buffer.flip(); byte[] bytes = new byte[buffer.remaining()]; buffer.get(bytes); System.out.println("READ FROM CLIENT:" + new String(bytes)); } if (count < 0) { channel.close(); } } catch (IOException e) { e.printStackTrace(); } } }
package com.nio.basic; import java.io.IOException; import java.net.InetSocketAddress; import java.nio.ByteBuffer; import java.nio.channels.SocketChannel; import java.util.Random; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; /** * nio 客户端 * Created by sdc on 2017/8/13. */ public class NioClient { public static void main(String[] args) { ExecutorService executorService = Executors.newCachedThreadPool(); executorService.submit(new Client("nio-client-1")); executorService.submit(new Client("nio-client-2")); executorService.submit(new Client("nio-client-3")); executorService.shutdown(); } static class Client extends Thread { private String clientThreadName; ByteBuffer buffer = ByteBuffer.allocate(1024); Random random = new Random(20); Client(String clientThreadName) { this.clientThreadName = clientThreadName; } @Override public void run() { SocketChannel channel = null; try { channel = SocketChannel.open(); channel.configureBlocking(false); channel.connect(new InetSocketAddress("localhost", 8000)); while (!channel.finishConnect()) { TimeUnit.MICROSECONDS.sleep(100); } for (int i=0; i<5; i++) { TimeUnit.MICROSECONDS.sleep(100 * random.nextInt()); String message = "send message " + i + " from" + clientThreadName; buffer.put(message.getBytes()); buffer.flip(); //buffer先把数据读入到buffer,然后channel先把buffer中的数据写入到channel, channel.write(buffer); buffer.clear(); } } catch (IOException e) { e.printStackTrace(); } catch (InterruptedException e) { e.printStackTrace(); }finally { try { channel.close(); } catch (IOException e) { e.printStackTrace(); } } } } }
本文出自 “不积跬步无以至千里” 博客,请务必保留此出处http://shangdc.blog.51cto.com/10093778/1955874
以上是关于java nio之 channel通道的主要内容,如果未能解决你的问题,请参考以下文章