Channels和Buffers是JAVA NIO裡面比較重要的兩個概念,NIO正是基於Channels和Buffers進行數據操作,且數據總是從Channels讀取到Buffers,或者從Buffers寫入到Channels。
以FileChannel為例,如下:
FileChannel是文件寫入/讀取相關的通道;
產生FileChannel的方式:
下面舉個例子,分別從FileOutputStream、RandomAccessFile、FileInputStream中獲取文件通道,進行相關寫入/讀取操作;
package com.pichen.io; import java.nio.*; import java.nio.channels.*; import java.io.*; public class GetChannel { private static final int BSIZE = 1024; public static void main(String[] args) throws Exception { // 創建文件輸出字節流 FileOutputStream fos = new FileOutputStream("data.txt"); //得到文件通道 FileChannel fc = fos.getChannel(); //往通道寫入ByteBuffer fc.write(ByteBuffer.wrap("Some text ".getBytes())); //關閉流 fos.close(); //隨機訪問文件 RandomAccessFile raf = new RandomAccessFile("data.txt", "rw"); //得到文件通道 fc = raf.getChannel(); //設置通道的文件位置 為末尾 fc.position(fc.size()); //往通道寫入ByteBuffer fc.write(ByteBuffer.wrap("Some more".getBytes())); //關閉 raf.close(); //創建文件輸入流 FileInputStream fs = new FileInputStream("data.txt"); //得到文件通道 fc = fs.getChannel(); //分配ByteBuffer空間大小 ByteBuffer buff = ByteBuffer.allocate(BSIZE); //從通道中讀取ByteBuffer fc.read(buff); //調用此方法為一系列通道寫入或相對獲取 操作做好准備 buff.flip(); //從ByteBuffer從依次讀取字節並打印 while (buff.hasRemaining()){ System.out.print((char) buff.get()); } fs.close(); } }
再舉個文件復制的例子,有兩種方式:
如下代碼示例:
package com.pichen.io; import java.nio.*; import java.nio.channels.*; import java.io.*; public class ChannelCopy { private static final int BSIZE = 1024; public static void main(String[] args) throws Exception { //獲取文件輸入輸出字節流 FileInputStream fis = new FileInputStream("C:\\test.jpg"); FileOutputStream fos = new FileOutputStream("C:\\test_copy.jpg"); //從文件輸入輸出字節流中獲取通道 FileChannel fci = fis.getChannel(); FileChannel fco = fos.getChannel(); //分配ByteBuffer空間大小 ByteBuffer buffer = ByteBuffer.allocate(BSIZE); //第一種種數據拷貝方式,直接往輸入通道寫數據 while (fci.read(buffer) != -1) { //為寫入操作做准備 buffer.flip(); //往輸出通道寫入buffer fco.write(buffer); //清空buffer,重置內部指針 buffer.clear(); } //第二種數據拷貝方式,利用transferTo或者transferFrom方式 FileOutputStream fos2 = new FileOutputStream("C:\\test_copy2.jpg"); FileChannel fco2 = fos.getChannel(); fci.transferTo(0, fci.size(), fco2); fis.close(); fos.close(); fos2.close(); } }
buffer用於與通道進行交互,舉個例子如下,這裡以ByteBuffer為例;
package com.pichen.io; import java.nio.*; import java.nio.channels.*; import java.io.*; public class GetChannel { private static final int BSIZE = 1024; public static void main(String[] args) throws Exception { // 隨機訪問文件 RandomAccessFile raf = new RandomAccessFile("C:\\data.txt", "rw"); // 得到文件通道 FileChannel fc = raf.getChannel(); ByteBuffer bf = ByteBuffer.allocate(BSIZE); int bytesRead = fc.read(bf); // read into buffer. while (bytesRead != -1) { // 通過flip()方法將Buffer從寫模式切換到讀模式 bf.flip(); while (bf.hasRemaining()) { // 每次讀取一個字節 System.out.print((char) bf.get()); } // 清空緩存,准備往緩存寫數據 bf.clear(); bytesRead = fc.read(bf); } // 關閉 raf.close(); } }
compact
:往buffer寫數據之前調用,只清除已讀取的數據,新寫入的數據會添加到未讀數據末尾;(
Buffer
buffer)方法
,調用Buffer的put方法
write
(
Buffer
buffer)方法
調用Buffer的get方法
參考:http://ifeve.com/java-nio-all/