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();
}
}
}
}
}
JAVA NIO Selector 知识三 http://shangdc.blog.51cto.com/10093778/1956602
JAVA NIO buffer (知识三)
http://shangdc.blog.51cto.com/10093778/1956602
JAVA NIO 之 channel通道(知识二)
http://shangdc.blog.51cto.com/10093778/1955874
JAVA NIO 知识一
http://shangdc.blog.51cto.com/10093778/1955793
转载于:https://blog.51cto.com/shangdc/1955874