Java NIO的通道类似流,但又有些不同:

  • 既可以从通道中读取数据,又可以写数据到通道。但流的读写通常是单向的。
  • 通道可以异步地读写。
  • 通道中的数据总是要先读到一个Buffer,或者总是要从一个Buffer中写入。

正如上面所说,从通道读取数据到缓冲区,从缓冲区写入数据到通道。

Channel的实现

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

  • FileChannel
  • DatagramChannel
  • SocketChannel
  • ServerSocketChannel

FileChannel 从文件中读写数据。

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

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

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

多数情况下,通道与操作系统的文件描述符(File Descriptor)和文件句柄(File Handle)有着一对一的关系(通道比文件描述符更广义)。

Channel接口:

public interface Channel
{
public boolean isOpen( );
public void close( ) throws IOException;
}

  与缓冲区不同,通道API主要由接口指定。不同的操作系统上通道实现(Channel Implementation)会有根本性的差异,所以通道API仅仅描述了可以做什么。因此很自然地,通道实现经常使用操作系统的本地代码。通道接口允许您以一种受控且可移植的方式来访问底层的I/O服务。

InterruptibleChannel接口:

  InterruptibleChannel是一个标记接口,当被通道使用时可以标示该通道是可以中断的(Interruptible)。如果连接可中断通道的线程被中断,那么该通道会以特别的方式工作。

两个对应的核心抽象类:

  这两个类是AbstractInterruptibleChannel和AbstractSelectableChannel,它们分别为可中断的(interruptible)和可选择的(selectable)的通道实现提供所需的常用方法。尽管描述通道行为的接口都是在java.nio.channels包中定义的,不过具体的通道实现却都是从java.nio.channels.spi中的类引申来的。这使得他们可以访问受保护的方法,而这些方法普通的通道用户永远都不会调用。

获取管道的集中常见操作:

ServerSocketChannel ssc = ServerSocketChannel.open( );
ssc.socket( ).bind (new InetSocketAddress (8080)); SocketChannel sc = SocketChannel.open( );
sc.connect (new InetSocketAddress("localhost", 8080)); DatagramChannel dc = DatagramChannel.open( ); RandomAccessFile raf = new RandomAccessFile ("E:\\JcloudMyProject\\blogcode\\src\\main\\java\\heapStark\\blogCode\\nio\\Main.java", "r");
FileChannel fc = raf.getChannel( );
//Socket 无法产生Channel
Socket socket = new Socket();
socket.connect( new InetSocketAddress("localhost",8080));
assert (socket.getChannel()==null);

Socket类也有新的getChannel( )方法。这些方法虽然能返回一个相应的socket通道对象,但它们却并非新通道的来源,RandomAccessFile.getChannel( )方法才是。只有在已经有通道存在的时候,Socket类的getChannel( )方法才返回与一个socket关联的通道否则返回空。

关闭通道:

  与缓冲区不同,通道不能被重复使用。一个打开的通道即代表与一个特定I/O服务的特定连接并封装该连接的状态。当通道关闭时,那个连接会丢失,然后通道将不再连接任何东西。调用通道的close( )方法时,可能会导致在通道关闭底层I/O服务的过程中线程暂时阻塞,哪怕该通道处于非阻塞模式。通道关闭时的阻塞行为(如果有的话)是高度取决于操作系统或者文件系统的。在一个通道上多次调用close( )方法是没有坏处的,但是如果第一个线程在close( )方法中阻塞,那么在它完成关闭通道之前,任何其他调用close( )方法都会阻塞。后续在该已关闭的通道上调用close( )不会产生任何操作,只会立即返回。尝试进行任何需要通道处于开放状态作为前提的操作,如读、写等都会导致ClosedChannelException异常。

ByteChannel继承关系:

  ByteChannel接口本身并不定义新的API方法,它是一种用来聚集它自己以一个新名称继承的多个接口的便捷接口。根据定义,实现ByteChannel接口的通道会同时实现ReadableByteChannel 和WritableByteChannel两个接口,所以此类通道是双向的。这是简化类定义的语法糖(syntactic sugar)。

阻塞(blocking)或非阻塞(nonblocking):

  通道可以以阻塞(blocking)或非阻塞(nonblocking)模式运行。非阻塞模式的通道永远不会让调用的线程休眠。请求的操作要么立即完成,要么返回一个结果表明未进行任何操作。只有面向流的(stream-oriented)的通道,如sockets和pipes才能使用非阻塞模式。SocketChannel通道类从SelectableChannel引申而来。从SelectableChannel引申而来的类可以和支持有条件的选择(readiness selectio)的选择器(Selectors)一起使用。将非阻塞I/O和选择器组合起来可以使您的程序利用多路复用I/O(multiplexed I/O)。

  • InterruptibleChannel接口,标记接口

如果一个线程在一个InterruptibleChannel通道上被阻塞并且同时被中断(由调用该被阻塞线程的interrupt( )方法的另一个线程中断),那么该通道将被关闭,

该被阻塞线程也会产生一个ClosedByInterruptException异常。此外,假如一个线程的interrupt status被设置并且该线程试图访问一个通道,

那么这个通道将立即被关闭,同时将抛出相同的ClosedByInterruptException异常。线程的interrupt status在线程的interrupt( )方法被调用时会被设置。

我们可以使用isInterrupted( )来测试某个线程当前的interrupt status。当前线程的interrupt status可以通过调用静态的Thread.interrupted( )方法清除。

仅仅因为休眠在其上的线程被中断就关闭通道,这看起来似乎过于苛刻了。不过这却是NIO架构师们所做出的明确的设计决定。经验表明,想要在所有的操作系统上一致而可靠地处理被中断的I/O操作是不可能的。“在全部平台上提供确定的通道行为”这一需求导致了“当I/O操作被中断时总是关闭通道”这一设计选择。这个选择被认为是可接受的,因为大部分时候一个线程被中断就是希望以此来关闭通道。java.nio包中强制使用此行为来避免因操作系统独特性而导致的困境,因为该困境对I/O区域而言是极其危险的。这也是为增强健壮性(robustness)而采用的一种经典的权衡。可中断的通道也是可以异步关闭的。实现InterruptibleChannel接口的通道可以在任何时候被关闭,即使有另一个被阻塞的线程在等待该通道上的一个I/O操作完成。当一个通道被关闭时,休眠在该通道上的所有线程都将被唤醒并接收到一个AsynchronousCloseException异常。接着通道就被关闭并将不再可用。

NIO Channel 管道的更多相关文章

  1. Java NIO Channel和Buffer

    Java NIO Channel和Buffer @author ixenos Channel和Buffer的关系 1.NIO速度的提高来自于所使用的结构更接近于OS执行I/O的方式:通道和缓冲器: 2 ...

  2. Java NIO Channel之FileChannel [ 转载 ]

    Java NIO Channel之FileChannel [ 转载 ] @author zachary.guo 对于文件 I/O,最强大之处在于异步 I/O(asynchronous I/O),它允许 ...

  3. Java NIO Channel通道

    原文链接:http://tutorials.jenkov.com/java-nio/channels.html Java NIO Channel通道和流非常相似,主要有以下几点区别: 通道可以读也可以 ...

  4. (三:NIO系列) Java NIO Channel

    出处: Java NIO Channel 1.1. Java NIO Channel的特点 和老的OIO相比,通道和NIO流(非阻塞IO)主要有以下几点区别: (1)OIO流一般来说是单向的(只能读或 ...

  5. NIO Channel Scatter/Gather 管道Pipe类

    通道提供了一种被称为Scatter/Gather的重要新功能(有时也被称为矢量I/O).Scatter/Gather是一个简单却强大的概念,它是指在多个缓冲区上实现一个简单的I/O操作.对于一个wri ...

  6. NIO之管道 (Pipe)

    Java NIO 管道是2个线程之间的单向数据连接.Pipe有一个source通道和一个sink通道.数据会被写到sink通道,从source通道读取. 代码使用示例: public static v ...

  7. [翻译] java NIO Channel

    原文地址:http://tutorials.jenkov.com/java-nio/channels.html JAVA NIO channels和流的概念很像,下面是他们的一些区别: 你可以对cha ...

  8. Java NIO Channel to Channel Transfers通道传输接口

    原文链接:http://tutorials.jenkov.com/java-nio/channel-to-channel-transfers.html 在Java NIO中如果一个channel是Fi ...

  9. NIO Channel和Buffer

    Java NIO 由以下几个核心部分组成: Buffer Channel Selector 传统的IO操作面向数据流,意味着每次从流中读一个或多个字节,直至完成,数据没有被缓存在任何地方.NIO操作面 ...

随机推荐

  1. pandas-05 map和replace操作

    # pandas-05 map和replace操作 map可以做一个映射,对于操作大型的dataframe来说就非常方便了,而且也不容易出错.replace的作用是替换,这个很好理解. import ...

  2. node.js数据库操作

    node 中使用mysql const http = require('http'); const mysql = require('mysql'); const url = require('url ...

  3. js 数据类型检测

    提起数据类型检测  大多数人首先想起的应该是  typeof 'xxx' == '数据类型' 坦然这种方法对于基本数据类型的检测还是非常方便的,但是当遇到引用数据类型 Object时却爱莫能助,下面就 ...

  4. 处理vue-quill-editor回显数据的时候没有空格问题

    这是我要实现的效果 这是我回显后的情况(可以看见空格都没有了) 处理后 处理方法  添加一个class="ql-editor" <quill-editor class=&qu ...

  5. Python实现柱状图【数字精准展示,使用不同颜色】

    一.简介 主要使用matplotlib基于python的可视化组件实现. 二.代码实现 # -*- coding: utf-8 -*- """ Created on Mo ...

  6. scrapy 爬虫中间件 deepth深度

    源码 class DepthMiddleware(object): def __init__(self, maxdepth, stats, verbose_stats=False, prio=1): ...

  7. GreenPlum数据库搭建原原则

    1.平衡: 性能 容量 成本 2.高可用(主节点高可用): 节点 网络 磁盘 3.部署方案: Master和Standby Master分机部署 primaty segment 与miiror Seg ...

  8. 云计算与大数据实验:Hbase shell操作成绩表

    [实验目的] 1)了解hbase服务 2)学会hbase shell命令操作成绩表 [实验原理] HBase是一个分布式的.面向列的开源数据库,它利用Hadoop HDFS作为其文件存储系统,利用Ha ...

  9. Python的logging模块详解

          Python的logging模块详解 作者:尹正杰  版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.日志级别 日志级别指的是产生的日志的事件的严重程度. 设置一个级别后,严重程度 ...

  10. Eclipse经常出现未响应问题

    修改eclipse.ini文件 -startupplugins/org.eclipse.equinox.launcher_1.5.0.v20180512-1130.jar--launcher.libr ...