Java - NIO之Channel(FileChannel)
一、關於Channel
Java NIO的通道(Channel)類似流,但又有些不同:
既可以從通道中讀取資料,又可以寫資料到通道。但流的讀寫通常是單向的。
通道可以非同步地讀寫。通道中的資料總是要先讀到一個Buffer,或者總是要從一個Buffer中寫入。
Java NIO中最重要的通道的實現:
FileChannel 從檔案中讀寫資料。
DatagramChannel 能通過UDP讀寫網路中的資料。
SocketChannel 能通過TCP讀寫網路中的資料。
ServerSocketChannel可以監聽新進來的TCP連線,像Web伺服器那樣。對每一個新進來的連線都會建立一個SocketChannel。
二、關於FileChannel
Java NIO中的FileChannel是一個連線到檔案的通道,可以通過檔案通道讀寫檔案。
FileChannel無法設定為非阻塞模式,它總是執行在阻塞模式下。
三、讀取檔案
/**
* 獲取檔案控制程式碼(相對於專案根路徑)
*/
RandomAccessFile file = new RandomAccessFile("nio-data.txt", "rw");
/**
* 獲取Channel
*/
FileChannel channel = file.getChannel();
/**
* 定義Buffer緩衝區,存放讀取到的資料。 大小 48byte
*/
ByteBuffer buf = ByteBuffer.allocate(48);
/**
* 從Channel中讀取資料寫到Buffer
*/
int bytesRead = channel.read(buf);
/**
* 迴圈讀取(判斷是否讀取完畢)
*/
while (bytesRead != -1) {
/**
* 翻轉Buffer的讀寫模式
*/
buf.flip();
/**
* 列印當前讀取到的資料
*/
while(buf.hasRemaining()){
System.out.print((char) buf.get());
}
/**
* 清空緩衝區,讓它可以再次被寫入
*/
buf.clear();
/**
* 繼續從Channel中讀取資料到Buffer
*/
bytesRead = channel.read(buf);
}
/**
* 關閉資源
*/
channel.close();
file.close();
四、寫入檔案
/**
* 準備工作
*/
String newData = "New String to write to file..." + System.currentTimeMillis();
RandomAccessFile file = new RandomAccessFile("nio-data.txt", "rw");
FileChannel channel = file.getChannel();
ByteBuffer buf = ByteBuffer.allocate(48);
buf.clear();
buf.put(newData.getBytes());
buf.flip();
/**
* 因為無法保證write()方法一次能向FileChannel寫入多少位元組,因此需要重複呼叫write()方法,直到Buffer中已經沒有尚未寫入通道的位元組
*/
while(buf.hasRemaining()) {
channel.write(buf);
}
channel.close();
file.close();
注意:因為沒有指定寫入的開始位置,如果原始檔中已經存在資料,這裡的寫入會從原始檔的開始位置替換到寫入資料的結束。
對於某個特定位置進行資料的讀/寫操作,可以通過呼叫position()方法獲取FileChannel的當前位置, 也可以通過呼叫position(long pos)方法設定FileChannel的當前位置。
size()方法將返回該例項所關聯檔案的大小
force(boolean metaData)方法將通道里尚未寫入磁碟的資料強制寫到磁碟上,metaData為true將包含許可權
/**
* 準備資料
*/
String newData = "New String to write to file..." + System.currentTimeMillis();
RandomAccessFile file = new RandomAccessFile("nio-data.txt", "rw");
FileChannel channel = file.getChannel();
/**
* 指定position為檔案大小的值,即在channel的末尾追加內容
*/
channel.position(channel.size());
ByteBuffer buf = ByteBuffer.allocate(48);
buf.clear();
buf.put(newData.getBytes());
buf.flip();
while(buf.hasRemaining()) {
channel.write(buf);
}
channel.close();
file.close();
六、檔案擷取
對檔案本身發生作用,需要寫許可權
RandomAccessFile file = new RandomAccessFile("nio-data.txt", "rw");
FileChannel channel = file.getChannel();
/**
* 擷取檔案前40byte
*/
channel.truncate(40);
channel.close();
file.close();
七、Channel-to-Channel傳輸
FileChannel類有這兩個獨有的方法方法:transferFrom()和testTransferTo(),因此Channel-to-Channel傳輸中通道之一必須是FileChannel。
直接的通道傳輸不會更新與某個FileChannel關聯的position值。
對於傳輸資料來源是一個檔案的transferTo()方法,如果position + count的值大於檔案的size值,傳輸會在檔案尾的位置終止。
/**
* 測試TransferFrom()
*/
@org.junit.Test
public void testTransferFrom() throws Exception{
/**
* 來源相關
*/
RandomAccessFile fromFile = new RandomAccessFile("fromFile.txt", "rw");
FileChannel fromChannel = fromFile.getChannel();
/**
* 目標相關
*/
RandomAccessFile toFile = new RandomAccessFile("toFile.txt", "rw");
FileChannel toChannel = toFile.getChannel();
/**
* 傳輸量
*/
long position = 0;
long count = fromChannel.size();
/**
* 執行傳輸(FileChannel to FileChannel)
*/
toChannel.transferFrom(fromChannel, position, count);
toChannel.close();
toFile.close();
fromChannel.close();
fromFile.close();
}
/**
* 測試TransferTo()
*/
@org.junit.Test
public void testTransferTo() throws Exception{
/**
* 來源相關
*/
RandomAccessFile fromFile = new RandomAccessFile("fromFile.txt", "rw");
FileChannel fromChannel = fromFile.getChannel();
/**
* 目標相關
*/
WritableByteChannel toChannel = Channels.newChannel(System.out);
/**
* 執行傳輸(檔案通道 to 普通通道)
*/
fromChannel.transferTo(0, fromChannel.size(), toChannel);
fromChannel.close();
fromFile.close();
}
相關文章
- Java NIO 之 Channel(通道)Java
- Java NIO系列教程(七) FileChannelJava
- Java-NIO之Channel(通道)Java
- Java NIO 檔案通道 FileChannel 用法Java
- Java NIO Channel 使用Java
- 【譯】Java NIO 簡明教程系列之 ChannelJava
- Java NIO - Channel 與 SelectorJava
- Java NIO系列教程(二) ChannelJava
- Java NIO:Buffer、Channel 和 SelectorJava
- Java NIO學習系列二:ChannelJava
- nio再學習之通道channel
- 【Java】NIO中Channel的註冊原始碼分析Java原始碼
- NIO(四)channel總結
- Java NIO之SelectorJava
- Java NIO之BufferJava
- Java Socket 之 NIOJava
- Java IO之NIOJava
- javaNIO實戰4----> java NIO的通道Channel實戰Java
- java nio中的select和channel是怎麼使用的?Java
- Java-NIO之SelectorJava
- NIO(六)selector和channel的使用
- 【譯】Java NIO 簡明教程系列之 NIO 概述Java
- Java NIO之Buffer的使用Java
- Java NIO 之緩衝區Java
- Java NIO之Scatter和GatherJava
- 【NIO】Buffer、Channel、Selector 關係小結
- 【譯】Java NIO 簡明教程系列之 NIO 簡介Java
- Java網路程式設計與NIO詳解4:淺析NIO包中的Buffer、Channel 和 SelectorJava程式設計
- NIO中SelectionKey和Channel、Selector的關係
- Java NIO之Selector(選擇器)Java
- Java NIO 之 Buffer(緩衝區)Java
- 初識NIO之Java小DemoJava
- Java-NIO之Buffer(緩衝區)Java
- Java NIO之擁抱Path和FilesJava
- FileChannel指南
- Java NIOJava
- Java NIO 系列文章之 淺析Reactor模式JavaReact模式
- Java NIO filesJava
- Java NIO - BufferJava