天天看点

NIO流,面向缓冲区流,一篇文章解决NIO流基础

NIO流和IO流的主要区别就在于IO流是直接面向文档的,读一个输出一个,NIO是面向的缓冲区

直接开始代码,NIO流的某些讲解都会在注释上

先来了解以下几个比较重要的参数

capacity: 缓冲区的容量,不可以为负数,一旦创建了就不能够改变

limit :无效缓冲区的第一个位置索引,limit后面的数据既不可读,也不可写

position :下一个可以被读取或者写入的缓冲区位置索引

mark:标记索引,该索引能够用于下次读取或者写入,它只能够在0-position之间

以及几个方法:

1、flip(): 将写模式切换为读模式, 将limit的值改为postion的值,同时将postion归0

特点: 就是为下一次数据的读取做好准备

2、clear(): 将读模式切换为写模式,将limit改为capacity的值,同时将postion归0

特点: 就是为下一次数据的写入做好准备

3、put(): 相对读取,向Buffer中存储数据

4、get(): 相对读取,从Buffer中获取数据

5、mark(): 设置标记位

先演示以下各种常用方法:

import java.nio.*;

public class NIOdemo {

public static void main(String[] args) {

ByteBuffer buffer = ByteBuffer.allocateDirect(10);//创建直接字节缓存区

CharBuffer buffers = CharBuffer.allocate(8);//创建字节缓存区

System.out.println("capacity:"+buffers.capacity());//缓冲区容量
System.out.println("limit:"+buffers.limit());//索引位置,就是最大能读取和写入的位置
System.out.println("position:"+buffers.position());//下一个可以被读取或者写入的缓冲区位置索引

buffers.put('1');
System.out.println("position:"+buffers.position());
buffers.put("623132");
System.out.println("position:"+buffers.position());


System.out.println("==============================================");


buffers.flip();//将写模式切换成读模式,就是说现在,我要从limit这个位置,开始读取数据,然后position归零
System.out.println("capacity:"+buffers.capacity());//缓冲区容量
System.out.println("limit:"+buffers.limit());//索引位置,就是最大能读取和写入的位置
System.out.println("position:"+buffers.position());//下一个可以被读取或者写入的缓冲区位置索引


System.out.println("==============读取==========");
char s = 0;
s = buffers.get();
System.out.println(s);

buffers.mark();//设置标记位置

s = buffers.get();
System.out.println(s);


buffers.reset();//重置回标记点
System.out.println(buffers.get());

while(buffers.hasRemaining()) {//判断这个通道内是否还有可以读取的数字
	System.out.println(buffers.get());
}

System.out.println("===================");
buffers.clear();//将postion清0,然后将limit = capactip
System.out.println(buffers.get());

 }
  }
           

然后进入实践操作:

先创建一个通道,通道内部添加上我们常用的IO流
             FileChannel inc = new FileInputStream(new File("src/XueXi.mp4")).getChannel();
             //通道的话你可以直接理解为字面意思,就是进入或者走出的通道
             FileChannel ouc = new FileOutputStream(new File("src/XueXi2.mp4")).getChannel();
             //这两行代码就是声明是通道ouc,给它赋值,赋值就是一个普通的FileOutputStream后面加上一个getChannel()就可以了
             
             然后创建一个缓冲区
             ByteBuffer buffer = ByteBuffer.allocateDirect(1024);
             //参数是创建的缓冲区的大小
             //注意,缓冲区我声明的是Byte类型的,你还可以声明字符型CharBuffer或者其他类型

             现在就是直接输出就可以了
             int len = 0;
             while((len = inc.read(buffer))!=-1){
                  buffer.flip;
                  //这一个参数是指它缓冲区读取到了哪里,它最大只能到相应的位置
                  //比如我文档 1025长度,我先走了一个1024,还剩1,那么我下次走的时候,写入最大也只能写入到1
                  ouc.write(buffer);//写入文档
                  buffer,clear();//这个函数时清空缓冲区
                  }
           

总结 : 这个代码就是复制了一个视频的文件,通过通道进入缓冲区,在从缓冲区添加进入XueXi2

现在,稍稍进阶,用随机流进行实践以及用上map方法

map方法就是将某一个通道的值全部或者一部分添加进入缓冲区
  try {
        先创建一个随机流
		RandomAccessFile acc = new RandomAccessFile("src\\_IO流基础_1\\基础.txt","rw");
		//下面的这个seek()方法时指定添加的位置在哪里
		acc.seek(10);
		//添加进去
		acc.write("1assssss".getBytes());
		//创建一个通道,参数时上面的 随机流acc
    	FileChannel chan = acc.getChannel();
    	创建一个Byte的缓冲区  然后将值添加进去,后面两个参数时从哪里开始,最大长度,也就是说,如果你的0变成2那么你要在acc.length()上-2
    	MappedByteBuffer mapp = chan.map(MapMode.READ_ONLY, 0, acc.length());
    	chan.position(acc.length());//这里指你要从这个文档的最后面开始添加啦,你不是复制,这个是给当前文档添加值
    	chan.write(mapp);
	
	} catch (Exception e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	}
           
NIO流,面向缓冲区流,一篇文章解决NIO流基础
NIO流,面向缓冲区流,一篇文章解决NIO流基础
NIO流,面向缓冲区流,一篇文章解决NIO流基础