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();
}