一、IO与NIO的区别
java.io 中最核心的一个概念是流(Stream),面向流的编程。一个流要么是输入流,要么是输出流,不可能同时即是输入流又是输出流。
java.nio中3个核心概念: Selector(选择器), Channel(通道)与Buffer(缓冲区)。在java.nio中,我们是面向块(block)或是缓冲区(buffer)编程的。
Buffer
Buffer本身就是一块内存,底层实现上,它实际上是个数组。数据的读、写都是通过Buffer来实现的。
除了数组之外,Buffer还提供了对于数据的结构化访问方式,并且可以追踪到系统的读写过程。
Java中的7种原生数据类型都有各自对应的Buffer类型,如IntBuffer,LongBuffer,ByteBuffer及CharBuffer等等,并没有BooleanBuffer
Channel
Channel指的是可以向其写入数据或是从中读取数据的对象,它类似于java.io中的Stream
所有数据的读写都是通过Buffer来进行的,永远不会出现直接向Channel写入数据的情况,或者直接从Channel读取数据的情况。
与Stream不同的是,Channel是双向的,一个流只可能是InputStream或是OutputStream,Channel打开后则可以进行读取、写入或是读写。
由于Channel是双向的,因此它能更好地反映出底层操作系统的真实情况;在Linux系统中,底层操作系统的通道就是双向的。
二、Nio的例子1
public class NioTest { public static void main(String[] args) { IntBuffer buffer = IntBuffer.allocate(10); for(int i = 0 ; i < buffer.capacity(); i++){ int randomNumber = new SecureRandom().nextInt(20); buffer.put(randomNumber); } buffer.flip(); while (buffer.hasRemaining()){ System.out.println(buffer.get()); } } }
flip是进行切换成读。
打印结果:
三、传统IO切换成NIO对象
public class NioTest2 { public static void main(String[] args) throws Exception { FileInputStream fileInputStream = new FileInputStream("NioText2.txt"); FileChannel fileChannel = fileInputStream.getChannel(); ByteBuffer byteBuffer = ByteBuffer.allocate(512); fileChannel.read(byteBuffer); //操作反转 byteBuffer.flip(); while (byteBuffer.remaining() > 0){ byte b = byteBuffer.get(); System.out.println("Character:" + (char)b ); } fileChannel.close(); } }
新建NioText.txt文件
输出结果
四、例子3
将信息写入NioText3.txt文件中
public class NioTest3 { public static void main(String[] args) throws Exception { FileOutputStream fileOutputStream = new FileOutputStream("NioText3.txt"); FileChannel fileChannel = fileOutputStream.getChannel(); ByteBuffer byteBuffer = ByteBuffer.allocate(512); byte[] message = "hello world, welcome".getBytes(); for(int i = 0; i < message.length ; i++){ // 将信息写入byteBuffer里 byteBuffer.put(message[i]); } byteBuffer.flip(); //将byteBuffer信息写入fileChannel fileChannel.write(byteBuffer); fileChannel.close(); } }