天天看點

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流基礎