1.概念
nio中拥有3个核心概念:
Selector
,Channel
与Buffer
。
在nio
中我们是面向块(block) 或是面向缓冲区(buffer)编程的。底层实现上,它实际是个数组,数据的读和写都是通过Buffer
来实现的。
除了数组之外,Buffer还提供了对数据的结构化访问方式
,并且可以追踪到系统的读写过程
。
注意:
Java中的7种原生数据类型都有各自对应的Buffer类型,如IntBuffer,LongBuffer,ByteBuffer及CharBuffer等等,并没有BooleanBuffer类型(There is one subclass of this class for each non-boolean primitive type
)。
1.IO与NIO的对比
IO
: 最为核心的一个概念是流(Stream),面向流的编程。Java中一个流要么是输入流,要么是输出流,不可能同时输入流又是输出流
NIO
: Channel指的是可以向其写入数据或是从中读取数据的对象,它类似于java.io种stream,但注意,所有的数据的读写都是通过Buffer来进行的,永远不会出现直接向Channel种写入数据的情况,或是直接从Channel读取数据的情况。与Stream不同的是,Channel是双向的,一个流只可能是InputStream或是OutputStream,Channel打开后则可以进行读取、写入或是读写。由于Channel是双向的,因此它能更好的反映出低层操作系统的真实情况;在Linux系统中,低层操作系统的通道就是双向的。
2.入门程序
//程序1
public class NioTest {
public static void main(String[] args) {
IntBuffer buffer = IntBuffer.allocate(10);
for (int i = 0; i < buffer.capacity(); i++) {
//SecureRandom是java.util.Random的子类,这个类更健壮一些,推荐使用
int random = new SecureRandom().nextInt(20);
buffer.put(random);
}
//实现读写的切换
buffer.flip();
while (buffer.hasRemaining()) {
System.out.println(buffer.get());
}
}
}
//程序2
public static void main(String[] args) throws IOException {
FileInputStream fileInputStream = new FileInputStream("NioTest.txt");
FileChannel channel = fileInputStream.getChannel();
ByteBuffer buffer = ByteBuffer.allocate(512);
channel.read(buffer);
buffer.flip();
while (buffer.remaining() > 0) {
byte b = buffer.get();
System.out.println("Character: " + (char) b);
}
fileInputStream.close();
}
//程序3
public static void main(String[] args) throws IOException {
FileOutputStream fileOutputStream = new FileOutputStream("NioTest.txt");
FileChannel channel = fileOutputStream.getChannel();
ByteBuffer buffer = ByteBuffer.allocate(512);
byte[] message = "hello world java,nihao".getBytes();
for (byte b : message) {
buffer.put(b);
}
buffer.flip();
channel.write(buffer);
fileOutputStream.close();
}