3、通道
Channle主要分为两类:File操作对应的FIleChannel和Stream操作对应的socket的3个channe。
1、这3个channel都是抽象类。其具体实现在SPI里面。
2、这3个channel都是双向的,都实现了ByteChannel。
3、网络Channel可工作在非阻塞模式下,是可配置的FileChannel在NIO里面只能工作在阻塞模式下。
4、4个Channel的操作都是可中断的。可中断的语义如下
问题:stream操作除了socket还有其他的吧?例如串口等
为什么FIleChannel不能工作在非阻塞模式下?
3.1.1打开通道
通道可以以多种方式创建。Socket 通道有可以直接创建新socket 通道的工厂方法。但是一个FileChannel 对象却只能通过在一个打开的RandomAccessFile、FileInputStream 或 FileOutputStream对象上调用getChannel( )方法来获取。您不能直接创建一个FileChannel 对象。File 和socket 通道会
SocketChannel sc = SocketChannel.open( );
sc.connect (new InetSocketAddress ("somehost", someport));ServerSocketChannel ssc = ServerSocketChannel.open( );ssc.socket( ).bind (new InetSocketAddress (somelocalport));DatagramChannel dc = DatagramChannel.open( );RandomAccessFile raf = new RandomAccessFile ("somefile", "r");FileChannel fc = raf.getChannel( );Reader和Writer不能用来产生Channel
3.1.2使用通道
1、Channel是针对于Byte操作的
2、ReadonluByteChannel和WritableByteChannel是单双工的,ByteChannle是全双工的。
3、每一个file和socket的channle都实现了ByteChannel,按理来说都应该是全双工的,socket的channel确实是全双工的,但是FileChannel则不一定。因为文件channel是和文件相关的,会受到文件的打开方式和文件的权限。
我们知道,一个文件可以在不同的时候以不同的权限打开。从FileInputStream 对象的getChannel( )方法获取的FileChannel 对象是只读的,不过从接口声明的角度来看却是双 向的,因为FileChannel 实现ByteChannel 接口。在这样一个通道上调用write( )方法将抛出未经检查的NonWritableChannelException 异常,因为FileInputStream 对象 总是以read-only 的权限打开文件。
4、通道可以以阻塞(blocking)或非阻塞(nonblocking)模式运行。非阻塞模式的通道?远不会让调用的线程阻塞。请求的操作要么立即完成,要么返回一个结果表明未进行任 何操作。只有面向流的(stream-oriented)的通道,如sockets 和pipes 才能使用非阻塞式。
5、4 个channel都是可中断的。已验证,是的,不只close,read和write也是可中断的
3.1.3关闭通道
1、调用通道的close( )方法时,可能会导致在通道关闭底层I/O服务的过程中线程暂时阻塞,哪怕该通道处于非阻塞模式。通道关闭时的阻塞行为(如果有的话)是高度取决于操作系统或者文件系统的。在一个通道上多次调用close( )方法是没有坏处的,但如果第一个线程在close( )方法中阻塞,那么在它完成关闭通道之前,任何其他调用close( )方法都会阻塞。后续在该已关闭的通道上调用close( )不会产生任何操作,只会立即返回。
2、
3.3 FileChannel
为什么FileChannel没有Stream IO那样的非阻塞模式?
1、块IO系统调用时内核态首先会检查是否已经暂存了页,如果没有只能让磁盘控制器去copy,然后线程阻塞。
问题:内存映射文件如果大量页被缓存在磁盘,那缺页中断是否线
程会阻塞,或者性能较差?
写IO因为只是将数据copy到内核态,然后磁盘器去写,那么线程应该不会阻塞吧?
2、Stream IO的非阻塞有选择器搭配
FileChannel的API
position
3.3.2文件锁定
锁和文件相关,和线程,文件句柄无关
3.4内存映射文件
问题:directBuffer的原理是内存映射,写完数据然后又读数据,在磁盘还没写数据的时候可能buffer的数据就变化了,具体是怎么做的
内存映射文件相对于直接内存有什么优势?
2、内存映射文件应该会尽量加载很多的页到内存
内存映射文件的3种模式:
只读,读写,写时复制
内存映射文件的回收?
full gc
load(),isloaded(),force()
load不能保证全部加载进内存,而且页也可能被移除内存。
force
问题:
一个文件既可以被读也可以被写吗?
一个文件可以被同时读和写,所以文件锁很有用
.getChannel可以产生多少个channel
相同的
问题:FileChnanel和文件BIO的对比?
1、FileChannel支持中断
2、FileChannel缓冲区有什么优势?(和数组应该差不多吧)
3、FileChannel无copy
4、内存映射文件,可以极大的优化随机读。
问题:内存映射文件的优点
1、零copy
2、无系统调用
3、数据可能更多的缓存在内存里(如果大量的数据依然存储在磁盘上,这时的性能怎么样?)