Java NIO小结 (一)

    自JDK1.4后,Java推出了New/IO(java.nio.*)。在JDK1.4之前,原IO(java.io.*)处理只能是stream的方式 逐个字节逐个字节读取或者写入。流处理方式性能低。而New/IO处理数据时以块为单位,系统的IO开销小,但IO性能高。



New/IO的4个核心概念

Buffer 处理IO时,数据的载体

Charset 把unicode字符进行编码成字节码或者把字节码反编成unicode字符

Channel 连接着能进行IO操作的实体,比如一个Channel可以连接一个输入流,也可以连接一个输出流,还可以连接一个输入流和一个输入流,根据channel上连接的具体的流,可以进行输入或输出操作。

SelectorSelectionKey 与Selectable Channel一起,定义了多路复用和Non-Blocking IO操作能力。


Blocking IO和Non-Blocking IO

阻塞IO模式下,任何IO操作会阻塞Channel直到这个IO操作完成后,方可在这个通道上进行其它IO操作。非阻塞模式下,一个IO操作调用时,通道不会被阻塞,即使这个IO操作只传输了少量数据甚至完全没有传输数据。非阻塞模式最适用于多路复用IO编程,比如服务器端socket编程。

 

在JDK1.4中,传统的IO与New/IO已经有很好的集成,在传统的io包中,可以使用Channel,但是要根据具体的输入和输出流来决定。比如下 面的代码先定义一个文件输入流,通过文件输入流的FileChannel读取文件的头512个字节到缓存中,然后使用utf-8编码器把缓存中的内容反编 码成一个utf-8字符串。

 

Charset utf8 = Charset.forName("utf-8");
ByteBuffer buffer = ByteBuffer.allocate(512);
FileInputStream fis = new FileInputStream("a.txt");
FileChannel fileChannel = fis.getChannel();
fileChannel.read(buffer);
buffer.flip();
String content = utf8.decode(buffer);

 

反之,用FileChannel写入文件也是相当的方便,和读取类似。FileChannel写入的方式依赖于输入流的打开方式。下面的代码以 Append方式打开一个文件输出流,用这个流的FileChannel写入编码后的“hello java new IO"字符串。

 

FileOutputStream fos = new FileOutputStream("a.txt", true);
FileChannel fileChannel = fos.getChannel();		 
fileChannel.write(utf8.encode("hello java new IO"));

 

使用Channel的优点在于channel是可以同时输入输出的,而不要像传统的io那样打开一个输入流,打开一个输出流,在读/写时,这两个流总是要配对使用,下面的代码展示如何用一个FileChannel做输入和输出两种IO操作。

Charset utf8 = Charset.forName("utf-8");
//以读写方式随机存储文件
RandomAccessFile raf = new RandomAccessFile("1.txt", "rws");
FileChannel fc = raf.getChannel();

//写入hello file channel到文件中
fc.write(utf8.encode("hello file channel"));

//分配10个字节缓存
ByteBuffer buff = ByteBuffer.allocate(10);

//从文件起始位置开始读取10个字节,并输出
fc.read(buff, 0);
buff.flip();
System.out.println(utf8.decode(buff)); // 输出hello file
fc.close();
raf.close();

 

 

 

[原创内容,版权所有,如有转载,请注明出处,如有错误之处,请指出,不胜感激]

你可能感兴趣的:(nio,non-blocking IO,blocking IO)