NIO——FileChannel

 FileChannel 是一個連接到文件的通道,使用 FileChannel 可以從文件讀數據,也可以向文件中寫入數據。Java NIO 的 FileChannel 是標準 Java IO 讀寫文件的替代方案。
 FileChannel 不能設置爲非阻塞的模式,也就是說 FileChannel 總是阻塞的。
 1、開啓 FileChannel
 在使用 FileChannel 之前必須先開啓。但是不能直接開啓一個 FileChannel,需要通過一個 InputStream、OutputStream 或者 RandomAccessFile 獲取它。下面是一個使用 RandomAccessFile 獲取一個 FileChannel 對象的示例:

RandomAccessFile aFile = new RandomAccessFile("data/nio-data.txt", "rw");
FileChannel inChannel = aFile.getChannel();

 2、從 FileChannel 中讀取數據
 從 FileChannel 中讀取數據可以通過調用其中的一個 read() 方法完成,下面是一個示例:

ByteBuffer buf = ByteBuffer.allocate(48);
int bytesRead = inChannel.read(buf);//將 Channel 中的數據讀入到 Buffer 

 首先要分配一個 Buffer,然後調用 FileChannel 的 read() 方法。從 FileChannel 中讀取數據就是將該 FileChannel 中的數據讀取到分配的 Buffer 中。read() 方法的返回值就是向 Buffer 中讀取了多少個字節,如果返回 -1,則說明該文件已經被讀取完了。
 3、向 FileChannel 中寫入數據
 向 FileChannel 中寫入數據需要調用 FileChannel 的 write() 方法,將 Buffer 對象作爲該方法的入參,示例如下:

String newData = "New String to write to file..." +  System.currentTimeMillis();

ByteBuffer buf = ByteBuffer.allocate(48);
buf.clear();
buf.put(newData.getBytes());

buf.flip();

while(buf.hasRemaining()) {
    channel.write(buf);// 將 Buffer 中的數據寫入到 Channel 中
}

 注意:要將 FileChannel.write() 方法的調用放在一個 while 循環中,因爲無法保證 write() 方法一次能將 Buffer 中的多少字節寫入到 FileChannel 中,因此我們需要重複的調用 write() 直到 Buffer 中沒有字節可以寫。
 4、關閉 FileChannel
 FileChannel 使用完之後必須關閉,示例如下:

channel.close(); 

 5、FileChannel 的 position
 如果想在 FileChannel 的某一個指定位置讀寫數據,可以通過調用 FileChannel 的 position() 方法來獲取當前的 position 值,也可以調用 FileChannel 的 position(long pos) 方法設置 position 的值,示例如下:

long pos channel.position();

channel.position(pos +123);

 如果設置的 position 值超出了 File 文件的最後位置,在讀取該 Channel 時就會返回 -1 ,即返回“讀取到文件的末尾”的標識。但此時若向 Channel 中寫入數據,該 Channel 連接的 File 會被“擴張”到這個設置的 position 值的位置,然後將數據寫入到這個 File 中,這會導致該 File 帶有“空洞”,存儲在磁盤上的這個物理文件就會不連續。
 6、FileChannel 的 size
 FileChannel 的 size() 方法會返回這個 FileChannel 連接的 File 文件的大小,示例如下:

long fileSize = channel.size();  

 7、FileChannel 的 截斷
 可以調用 FileChannel.truncate() 方法截斷一個 File。截斷時需要指定一個長度,示例如下:

channel.truncate(1024);

 本示例將文件長度截斷爲1024個字節。
 8、FileChannel 的強制
 FileChannel.force() 方法會將 Channel 中所有未寫入磁盤的數據強制寫入磁盤。由於性能的原因操作系統可能會將一些數據緩存在內存中,因此無法確切地保證數據被寫入到了磁盤,除非調用了 force() 方法。
 force() 方法採用布爾值作爲參數,指明是否同時應刷新文件的元數據信息(比如權限等)。
 下面是一個同時刷新數據和元數據的示例:

channel.force(true);
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章