在Java 7,AsynchronousFileChannel 被添加到了Java NIO中,使用AsynchronousFileChannel可以實作異步地讀取和寫入檔案資料,
創建一個AsynchronousFileChannel
我們可以使用AsynchronousFileChannel提供的靜態方法 open() 創建它,示例代碼如下:
Path path = Paths.get("data/test.xml");
AsynchronousFileChannel fileChannel =
AsynchronousFileChannel.open(path, StandardOpenOption.READ);
第一個引數是一個 PATH 的對像實體,它指向了那個與 AsynchronousFileChannel 相關聯的檔案,
第二個引數是一個或多個操作選項,它決定了 AsynchronousFileChannel 將對目標檔案做何種操作,示例代碼中我們使用了 StandardOpenOption.READ ,它表明我們將要對目標檔案進行讀操作,
讀取資料
AsynchronousFileChannel 提供了兩種讀取資料的方式,都是呼叫它本身的 read() 方法,下面將對兩種方式進行介紹,
使用Futrue讀取資料
第一種反式是呼叫 AsynchronousFileChannel 的 read() 方法,該方法反回一個 Future 型別的物件,
Future operation = fileChannelread(buffer, 0);
第一個引數是ByteBuffer,從 AsynchronousFileChannel 中讀取的資料先寫入這個 ByteBuffer ,
第二個引數表示從檔案讀取資料的開始位置,
此 read() 方法會立即回傳,即使整個讀的程序還沒有完全結束,我們可以通過operation.isDone()來檢查讀取是否完成,這里的 operation 是上面呼叫 read() 方法回傳的 Future 型別的實體,下面是一段詳細的代碼示例:
AsynchronousFileChannel fileChannel =
AsynchronousFileChannel.open(path, StandardOpenOption.READ);
ByteBuffer buffer = ByteBuffer.allocate(1024);
long position = 0;
Future<Integer> operation = fileChannel.read(buffer, position);
while(!operation.isDone());
buffer.flip();
byte[] data = https://www.cnblogs.com/MonsterJ/p/new byte[buffer.limit()];
buffer.get(data);
System.out.println(new String(data));
buffer.clear();
上面的程式首先創建了一個 AsynchronousFileChannel 物件,然后呼叫它的read()方法回傳一個Future,其中read()方法需要兩個引數,一個是ByteBuffer,另一個是讀取檔案的開始位置,然后通過回圈呼叫isDone() 方法檢測讀取程序是否完成,完成后 isDone()方法將回傳true,盡管這樣讓cpu空轉了一會,但是我們還是應該等讀取操作完成后再進行后續的步驟,
一旦讀取完成,資料被存盤到ByteBuffer,然后將資料轉化為字串既而輸出,
使用CompletionHandler讀取資料
第二種讀取資料的方式是呼叫AsynchronousFileChannel 的另一個多載 read() 方法,改方法需要一個CompletionHandler 作為引數,下面是代碼示例:
fileChannel.read(buffer, position, buffer, new CompletionHandler<Integer, ByteBuffer>() {
@Override
public void completed(Integer result, ByteBuffer attachment) {
System.out.println("result = " + result);
attachment.flip();
byte[] data = https://www.cnblogs.com/MonsterJ/p/new byte[attachment.limit()];
attachment.get(data);
System.out.println(new String(data));
attachment.clear();
}
@Override
public void failed(Throwable exc, ByteBuffer attachment) {
}
});
一旦讀取操作完成,CompletionHandler的 complete() 方法將會被呼叫,它的第一個引數是個 Integer型別,表示讀取的位元組數,第二個引數 attachment 是 ByteBuffer 型別的,用來存盤讀取的資料,它其實就是由 read() 方法的第三個引數,當前示例中,我們選用 ByteBuffer 來存盤資料,其實我們也可以選用其他的型別,
讀取失敗的時候,CompletionHandler的 failed()方法會被呼叫,
寫入資料
就像讀取一樣,我們同樣有兩種方式向 AsynchronousFileChannel 寫入資料,我們可以呼叫它的2個多載的 write() 方法,下面我們將分別加以介紹,
使用Future讀取資料
AsynchronousFileChannel也可以異步寫入資料,下面是一個完整的寫入示例:
Path path = Paths.get("data/test-write.txt");
AsynchronousFileChannel fileChannel =
AsynchronousFileChannel.open(path, StandardOpenOption.WRITE);
ByteBuffer buffer = ByteBuffer.allocate(1024);
long position = 0;
buffer.put("test data".getBytes());
buffer.flip();
Future<Integer> operation = fileChannel.write(buffer, position);
buffer.clear();
while(!operation.isDone());
System.out.println("Write done");
首先實體化一個寫入模式的 AsynchronousFileChannel, 然后創建一個 ByteBuffer 并寫入一些資料,再然后將資料寫入檔案,最后,檢查回傳的 Future,看是否寫入完成,
注意,寫入目標檔案要提前創建好,如果它不存在的話,writh() 方法會拋出一個 java.nio.file.NoSuchFileException,
我們可以用以下方式來解決這一問題:
if(!Files.exists(path)){
Files.createFile(path);
}
使用CompletionHandler寫入資料
我們也可以使用 CompletionHandler代替Future向AsynchronousFileChannel寫入資料,這種方式可以更加直接的知道寫入程序是否完成,下面是示例程式:
Path path = Paths.get("data/test-write.txt");
if(!Files.exists(path)){
Files.createFile(path);
}
AsynchronousFileChannel fileChannel =
AsynchronousFileChannel.open(path, StandardOpenOption.WRITE);
ByteBuffer buffer = ByteBuffer.allocate(1024);
long position = 0;
buffer.put("test data".getBytes());
buffer.flip();
fileChannel.write(buffer, position, buffer, new CompletionHandler<Integer, ByteBuffer>() {
@Override
public void completed(Integer result, ByteBuffer attachment) {
System.out.println("bytes written: " + result);
}
@Override
public void failed(Throwable exc, ByteBuffer attachment) {
System.out.println("Write failed");
exc.printStackTrace();
}
});
當寫入程式完成時,CompletionHandler的completed()方法將會被呼叫,相反的如果寫入失敗則會呼叫failed()方法,
要留意CompletionHandler的方法的引數 attachemnt是怎么使用的,
最后
私信回復 資料 領取一線大廠Java面試題總結+阿里巴巴泰山手冊+各知識點學習思維導+一份300頁pdf檔案的Java核心知識點總結!
這些資料的內容都是面試時面試官必問的知識點,篇章包括了很多知識點,其中包括了有基礎知識、Java集合、JVM、多執行緒并發、spring原理、微服務、Netty 與RPC 、Kafka、日記、設計模式、Java演算法、資料庫、Zookeeper、分布式快取、資料結構等等,

轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/102083.html
標籤:Java
上一篇:樹-二叉樹的基本概念
