JAVA NIO 之 channel通道(知识二)
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