NIO学习笔记(1)之组成、NIO与IO区别、NIO和IO如何影响应用程序的设计和通道

本文介绍了Java NIO的三个核心部分:Channels、Buffers和Selectors,以及NIO与IO的区别,如面向缓冲、非阻塞IO和选择器机制。通过示例展示了如何使用FileChannel进行数据读写,阐述了NIO如何影响应用程序设计。
摘要由CSDN通过智能技术生成

Java NIO

Java NIO 由以下几个核心部分组成: 

·        Channels

·        Buffers

·        Selectors

Channel 和 Buffer 
Channel 有点象流。 数据可以从Channel读到Buffer中(channel.read(buf)),也可以从Buffer 写到Channel(channel.write(buf))中。这里有个图示: 

Channel和Buffer有好几种类型。

Channel的实现类: 

·        FileChannel-------文件IO

·        DatagramChanne-------UDP网络IOl

·        SocketChannel-------TCP客户端网络IO

·        ServerSocketChannel-------TCP服务器端网络IO

Buffer的实现类: 

·        ByteBuffer

·        CharBuffer

·        DoubleBuffer

·        FloatBuffer

·        IntBuffer

·        LongBuffer

·        ShortBuffer

这些Buffer覆盖了你能通过IO发送的基本数据类型:byte, short, int,long, float, double 和 char。 
Selector 
Selector允许单线程处理多个 Channel。如果你的应用打开了多个连接(通道),但每个连接的流量都很低,使用Selector就会很方便。例如,在一个聊天服务器中。 

单线程中使用一个Selector处理3个Channel的图示: 


Selector的使用:

1、创建一个管道

2、打开一个selector

3、将管道注册到selector中,并指出它所关注的事件

4、selector.select();阻塞的方式获取就绪状态的管道

5、selector.selectedKey();获得就绪状态的管道的集合

6、通过迭代器,遍历这个集合。

Java NIO vs. IO

Java NIO和IO的主要区别  

IO

NIO

Stream oriented

Buffer oriented

Blocking IO

Non blocking IO

 

Selectors

1.     面向流与面向缓冲 

Java NIO和IO之间第一个最大的区别是,IO是面向流的,NIO是面向缓冲区的。

Java IO面向流意味着每次从流中读一个或多个字节,直至读取所有字节,它们没有被缓存在任何地方。同时,它不能前后移动流中的数据。

Java NIO面向缓存,数据放到缓冲区中,需要时可在缓冲区中前后移动。增加了灵活性。

2.     阻塞与非阻塞IO 

Java IO的各种流是阻塞的,调用read() 或 write()时,线程被阻塞,直到数据被读取,或数据完全写入。

Java NIO采用非阻塞模式,使一个线程从某通道发送请求读取数据,如果目前没有数据可用时,就什么都不会获取。而不是让线程阻塞,所以直至数据变的可以读取之前,该线程可以继续做其他的事情。 非阻塞写同上。

3.     选择器(Selectors) 

Java NIO的选择器允许一个单独的线程来监视多个输入通道,你可以注册多个通道使用一个选择器,然后使用一个单独的线程来“选择”通道:这些通道里已经有可以处理的输入,或者选择已准备写入的通道。这种选择机制,使得一个单独的线程很容易来管理多个通道。 

NIO和IO如何影响应用程序的设计 

数据处理 

在IO设计中,我们从InputStream或 Reader逐字节读取数据。

代码 

1.   Name: Anna  

2.   Age: 25  

3.   Email: anna@mailserver.com  

4.   Phone: 1234567890  

该文本行的流可以这样处理: 

Java代码 

1.   InputStream input = … ; // get the InputStream from the client socket  

2.   BufferedReader reader = new BufferedReader(new InputStreamReader(input));  

3.     

4.   String nameLine   = reader.readLine();  

5.   String ageLine    = reader.readLine();  

6.   String emailLine  = reader.readLine();  

7.   String phoneLine  = reader.readLine();  

 
从一个阻塞的流中读数据

NIO的实现会有所不同,下面是一个简单的例子:  

 
从一个通道里读数据,直到所有的数据都读到缓冲区里

通道(Channel)

·        既可以从通道中读取数据,又可以写数据到通道。但流的读写通常是单向的。

·        通道可以异步地读写。

·        通道中的数据总是要先读到一个Buffer,或者总是要从一个Buffer中写入。(管道与buffer打交道,线程与buffer打交道)

Channel的实现 

这些是Java NIO中最重要的通道的实现: 

·        FileChannel:从文件中读写数据。

·        DatagramChannel:能通过UDP读写网络中的数据。

·        SocketChannel:能通过TCP读写网络中的数据。

·        ServerSocketChannel:可以监听新进来的TCP连接,像Web服务器那样。对每一个新进来的连接都会创建一个SocketChannel。

基本的 Channel 示例 
下面是一个使用FileChannel读取数据到Buffer中的示例: 

Java代码 

1.   RandomAccessFile aFile = new RandomAccessFile("data/nio-data.txt""rw");  

2.   //获取的一个  文件的管道

3.   FileChannel inChannel = aFile.getChannel();  

4.   //开辟个缓冲区

5.   ByteBuffer buf = ByteBuffer.allocate(48);  

6.   //将文件内容通过管道读到缓存中  

7.   int bytesRead = inChannel.read(buf);  

8.   while (bytesRead != -1) {    

9.        System.out.println("Read " + bytesRead);  

10.       buf.flip();  //切换缓存读写模式

11.    

12.       while(buf.hasRemaining()){  

13.            System.out.print((char) buf.get());  

14.       }  

15.    

16.       buf.clear();  

17.       bytesRead = inChannel.read(buf);  

18.  }  

19.  aFile.close();  

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值