Java NIO学习笔记(1)

java.nio这个包是自从JDK1.4开始引入的,NIO是new    io的缩写,这个包提供更好的I/O性能。这个包提供了对基本类型的缓冲,提供I/O抽象Channels及新的多元的(multiplexed)、字符集的编码器和解码器、非阻塞(non-blocking)的I/O机制。

NIO API主要集中在java.nio和它的subpackages中:
java.nio
定义了Buffer及其数据类型相关的子类。其中被java.nio.channels中的类用来进行IO操作的ByteBuffer的作用非常重要。
java.nio.channels
定义了一系列处理IO的Channel接口以及这些接口在文件系统和网络通讯上的实现。通过Selector这个类,还提供了进行异步IO操作的办法。这个包可以说是NIO API的核心。
java.nio.channels.spi
定义了可用来实现channel和selector API的抽象类。
java.nio.charset
定义了处理字符编码和解码的类。
java.nio.charset.spi
定义了可用来实现charset API的抽象类。
java.nio.channels.spi和java.nio.charset.spi这两个包主要被用来对现有NIO API进行扩展,在实际的使用中,我们一般只和另外的3个包打交道。下面将对这3个包一一介绍。

上面列的那些包基本不会使用,因为他们只是提供这些特性的支持,而你使用这些特性根本不需要你去了解它是怎么实现的,我们只需要根据他提供的api来实现相应的功能即可。

在java.io包里面提供的FileInputStream等类都提供了getChannels、close等方法。在java.net包里面的一些类也做了相应的改变。

在nio里面,比较重要的一个接口就是Channel,先看一下JDK对这个接口的描述:

通道表示到实体,如硬件设备、文件、网络套接字或可以执行一个或多个不同 I/O 操作(如读取或写入)的程序组件的开放的连接。

通道可处于打开或关闭状态。创建通道时它处于打开状态,一旦将其关闭,则保持关闭状态。一旦关闭了某个通道,试图对其调用 I/O 操作就会导致 ClosedChannelException 被抛出。通过调用通道的 isOpen 方法可测试通道是否处于打开状态。

正如扩展和实现此接口的各个接口和类规范中所描述的,一般情况下通道对于多线程的访问是安全的。

这个接口只提供了两个方法:
close()
    关闭此通道。
isOpen()
判断此通道是否处于打开状态。

这篇文章只介绍nio在网络和文件io方面的应用,下面只介绍FileChannel、ServerChannel和SocketChannel。

在文件io上的应用
FileChannel接口介绍:
用于读取、写入、映射和操作文件的通道。
常用的有下面几个方法:
lock()
获取对此通道的文件的独占锁定。
position()
设置此通道的文件位置。
read(ByteBuffer dst)
将字节序列从此通道读入给定的缓冲区。
size()
返回此通道的文件的当前大小。
transferFrom(ReadableByteChannel src, long position, long count)
将字节从给定的可读取字节通道传输到此通道的文件中。
transferTo(long position, long count, WritableByteChannel target)
将字节从此通道的文件传输到给定的可写入字节通道。
write(ByteBuffer src)
将字节序列从给定的缓冲区写入此通道。

下面给出一个文件复制的一个实例,代码如下:
public static void copyFileUsingNIO(String src, String dest)
     throws Exception {
    FileInputStream srcStream = new FileInputStream(src);
    FileOutputStream destStream = new FileOutputStream(dest);
    FileChannel inChannel=srcStream.getChannel();
    FileChannel outChannel=destStream.getChannel();
 
    inChannel.transferTo(0, inChannel.size(), outChannel);
 
    inChannel.close();
    outChannel.close();
    srcStream.close();
    destStream.close();
}
从上面可以看出在文件io中使用nio相当简单,只需要取得通道,然后传输就可以了。当然,也可以自己指定使用的buffer,使用read和write方法来操作io。

关于网络io方面下次介绍。

你可能感兴趣的:(java,jdk,多线程,.net,网络应用)