JAVA NIO 之 channel通道(知识二)

简介:

java nio 通道上一篇文章里就讲述过,channel总是写数据的时候,要先把数据写入到bytebuffer,读数据的时候总是要先从channel中读入到bytebuffer。如下图,这个图是好多知名博客常用的图,很好理解这个channel。

wKioL1mPKOfiRUviAAAlAoB14ME679.png-wh_50


channel分为一下几种:

  1. FileChannel

  2. SocketChannel

  3. ServerSocketChannel

  4. 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

相关文章
|
Java 大数据
解析Java中的NIO与传统IO的区别与应用
解析Java中的NIO与传统IO的区别与应用
|
8月前
|
缓存 网络协议 Java
JAVA网络IO之NIO/BIO
本文介绍了Java网络编程的基础与历史演进,重点阐述了IO和Socket的概念。Java的IO分为设备和接口两部分,通过流、字节、字符等方式实现与外部的交互。
248 0
|
10月前
|
监控 Java API
探索Java NIO:究竟在哪些领域能大显身手?揭秘原理、应用场景与官方示例代码
Java NIO(New IO)自Java SE 1.4引入,提供比传统IO更高效、灵活的操作,支持非阻塞IO和选择器特性,适用于高并发、高吞吐量场景。NIO的核心概念包括通道(Channel)、缓冲区(Buffer)和选择器(Selector),能实现多路复用和异步操作。其应用场景涵盖网络通信、文件操作、进程间通信及数据库操作等。NIO的优势在于提高并发性和性能,简化编程;但学习成本较高,且与传统IO存在不兼容性。尽管如此,NIO在构建高性能框架如Netty、Mina和Jetty中仍广泛应用。
264 3
|
10月前
|
存储 监控 Java
Java的NIO体系
通过本文的介绍,希望您能够深入理解Java NIO体系的核心组件、工作原理及其在高性能应用中的实际应用,并能够在实际开发中灵活运用这些知识,构建高效的Java应用程序。
290 5
|
11月前
|
消息中间件 缓存 Java
java nio,netty,kafka 中经常提到“零拷贝”到底是什么?
零拷贝技术 Zero-Copy 是指计算机执行操作时,可以直接从源(如文件或网络套接字)将数据传输到目标缓冲区, 而不需要 CPU 先将数据从某处内存复制到另一个特定区域,从而减少上下文切换以及 CPU 的拷贝时间。
java nio,netty,kafka 中经常提到“零拷贝”到底是什么?
|
存储 网络协议 Java
Java NIO 开发
本文介绍了Java NIO(New IO)及其主要组件,包括Channel、Buffer和Selector,并对比了NIO与传统IO的优势。文章详细讲解了FileChannel、SocketChannel、ServerSocketChannel、DatagramChannel及Pipe.SinkChannel和Pipe.SourceChannel等Channel实现类,并提供了示例代码。通过这些示例,读者可以了解如何使用不同类型的通道进行数据读写操作。
209 0
Java NIO 开发
|
Java
让星星⭐月亮告诉你,Java NIO之Buffer详解 属性capacity/position/limit/mark 方法put(X)/get()/flip()/compact()/clear()
这段代码演示了Java NIO中`ByteBuffer`的基本操作,包括分配、写入、翻转、读取、压缩和清空缓冲区。通过示例展示了`position`、`limit`和`mark`属性的变化过程,帮助理解缓冲区的工作原理。
141 2
|
Java
"揭秘Java IO三大模式:BIO、NIO、AIO背后的秘密!为何AIO成为高并发时代的宠儿,你的选择对了吗?"
【8月更文挑战第19天】在Java的IO编程中,BIO、NIO与AIO代表了三种不同的IO处理机制。BIO采用同步阻塞模型,每个连接需单独线程处理,适用于连接少且稳定的场景。NIO引入了非阻塞性质,利用Channel、Buffer与Selector实现多路复用,提升了效率与吞吐量。AIO则是真正的异步IO,在JDK 7中引入,通过回调或Future机制在IO操作完成后通知应用,适合高并发场景。选择合适的模型对构建高效网络应用至关重要。
325 2
|
安全 Java Linux
(七)Java网络编程-IO模型篇之从BIO、NIO、AIO到内核select、epoll剖析!
IO(Input/Output)方面的基本知识,相信大家都不陌生,毕竟这也是在学习编程基础时就已经接触过的内容,但最初的IO教学大多数是停留在最基本的BIO,而并未对于NIO、AIO、多路复用等的高级内容进行详细讲述,但这些却是大部分高性能技术的底层核心,因此本文则准备围绕着IO知识进行展开。
417 1
|
网络协议 C# 开发者
WPF与Socket编程的完美邂逅:打造流畅网络通信体验——从客户端到服务器端,手把手教你实现基于Socket的实时数据交换
【8月更文挑战第31天】网络通信在现代应用中至关重要,Socket编程作为其实现基础,即便在主要用于桌面应用的Windows Presentation Foundation(WPF)中也发挥着重要作用。本文通过最佳实践,详细介绍如何在WPF应用中利用Socket实现网络通信,包括创建WPF项目、设计用户界面、实现Socket通信逻辑及搭建简单服务器端的全过程。具体步骤涵盖从UI设计到前后端交互的各个环节,并附有详尽示例代码,助力WPF开发者掌握这一关键技术,拓展应用程序的功能与实用性。
667 0