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