天天看點

Java Nio 八、Java NIO FileChannel

最後更新時間:2014-06-25

一個Java NIO FileChannel是一個連接配接到檔案的通道。使用一個檔案通道你可以從一個檔案中讀取資料,以及寫資料到檔案中。這個Java NIO FileChannel類同标準的Java IO API是一個可供選擇的讀檔案操作。

一個FileChannel不能設定為非堵塞模式。它總是運作在堵塞模式下。

打開一個FileChannel

在你使用一個FileChannel之前,你必須打開它。你不能直接打開一個FileChannel。你需要通過一個InputStream,OutputStream,或者一個RandomAccessFile去擷取一個FileChannel。這裡有一個通過一個RandomAccessFile如何去打開一個FileChannel:

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

從FileChannel中讀取資料

為了從FileChannel讀取資料,你需要調用read()方法中的一個。這裡有一個例子:

ByteBuffer buf = ByteBuffer.allocate(48);

int bytesRead = inChannel.read(buf);
           

首先一個Buffer被配置設定了。這個資料從FileChannel中讀到Buffer中。

第二步這個FileChannel.read()方法被調用了。這個方法讀取來自FileChannel中的資料進入Buffer。通過read方法傳回的int值告訴你有多少個位元組寫進了Buffer中。如果傳回的值是-1,那就達到了檔案的結尾了。

寫資料進入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);
}
           

注意FileChannel.write方法在while循環中是怎麼被調用的。這個write方法不會保證有多少位元組會寫入到FileChannel。是以我們會重複write方法的調用直到這個buffer中沒有更多的位元組可寫了。

關閉一個FileChannel

當你使用一個FileChannel多一些事情的時候,你必須關閉它。這裡有一個執行個體怎麼做他:

channel.close();
           

FileChannel位置定位

當你在指定的位置讀或者寫一個FileChannel的時候。你可以通過調用position方法擷取FileChannel對象的目前位置。

你也可以通過調用position(long pos)方法設定FileChannel的位置。

這裡有兩個例子:

long pos channel.position();

channel.position(pos +123);
           

如果你在檔案的結尾設定了這個位置,并且試着從FileChannel中讀取資料,你将會得到-1(檔案結束符标記)

如果你在檔案的結尾設定了這個位置,并且寫資料到FileChannel,這個檔案将會被擴充适應這個位置去寫資料。這個可能發生在一個“檔案洞”裡面,在寫資料中磁盤上的實體檔案有一個缺口的地方。

FileChannel大小

FileChannel對象的size方法傳回了這個通道連接配接到的那個檔案的檔案大小。這裡有一個簡單的例子:

long fileSize = channel.size(); 
           

FileChannel截取

你可以通過調用FileChannel.truncate()方法截取一個檔案。當你截取一個檔案的時候,在給予的長度的地方截取他(将會丢棄掉這個檔案新結束的位元組,即從這個長度到最後的位元組會丢棄掉)。這裡有一個簡單的例子:

channel.truncate(1024);
           

這個例子是在1024個位元組處截取這個檔案。

FileChannel Force

這個FileChannel.force()方法會把來自channel中所有未寫的資料寫到磁盤中去。一個作業系統可能因為性能的原因會緩存資料到記憶體中,以至于你不能保證寫到channel中的資料确定的寫到磁盤中了,知道你調用force()方法。

這個force()方法有一個boolean類型的作為參數,告訴這個檔案的中繼資料(權限等等)是否也應該被寫入。

這裡有一個既會寫資料也會寫中繼資料到磁盤的例子:

channel.force(true);
           

翻譯位址:http://tutorials.jenkov.com/java-nio/file-channel.html