java nio 通道上一篇文章里就讲述过,channel总是写数据的时候,要先把数据写入到bytebuffer,读数据的时候总是要先从channel中读入到bytebuffer。如下图,这个图是好多知名博客常用的图,很好理解这个channel。
channel分为一下几种:
-
FileChannel
-
SocketChannel
-
ServerSocketChannel
-
DatagramChannel
FileChannel:
经常说的FileChannel都是拿下面的例子说事
代码如下:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
|
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();
}
}
}
}
} |
还有这样的例子:
|
1
2
|
FileInputStream is = new FileInputStream(new File(src));
FileChannel channelFrom = is.getChannel(); |
其实这两个是用到了nio的channel,不妨自己写一个例子试试。
SocketChannel和ServerSocketChannel一般是两个集合起来说的,一个用于客户端连接,一个用于服务端连接。
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
|
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();
}
}
} |
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
|
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
本文转自 豆芽菜橙 51CTO博客,原文链接:http://blog.51cto.com/shangdc/1955874