FileChannel是什么
它是用于讀取、寫入、映射和操作檔案的通道,除了熟悉的位元組通道讀取,寫入和關閉操作之外,此類還定義了以下特定于檔案的操作:
-
可以以不影響通道當前位置的方式在檔案中的絕對位置讀取或寫入位元組,
-
檔案的區域可以直接映射到記憶體中, 對于大檔案,這通常比呼叫通常的讀取或寫入方法要有效得多,
-
對檔案所做的更新可能會被強制發送到基礎存盤設備,以確保在系統崩潰時不會丟失資料,
-
位元組可以從檔案傳輸到其他通道,反之亦然,可以通過許多作業系統進行優化,將位元組快速傳輸到檔案系統快取或直接從檔案系統快取傳輸,
-
檔案的區域可能被鎖定,以防止其他程式訪問,
FileChannel配合著ByteBuffer,將讀寫的資料快取到記憶體中,然后以批量/快取的方式read/write,省去了非批量操作時的重復中間操作,操縱大檔案時可以顯著提高效率,ByteBuffer可以使用直接記憶體(系統記憶體)(allocateDirect),使用后無需jvm回收,
總結一下,按照位元組讀取,對大檔案讀取效率更高,無法設定為非阻塞模式,它總是運行在阻塞模式下,
但有時候我們要按照行讀取檔案,而FileChannel只能按照位元組讀取,所以這里需要對換行進行判斷一下,在這里我對其進行了實作,供大家參考,
實作
import java.io.*;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
public class test1 {
public static void readLineByChannel(String path) throws IOException {
long lineNumber = 0;
FileInputStream fileIn = new FileInputStream(path);
FileChannel fileChannel = fileIn.getChannel();
// 開始按行讀取
int bufferSize = 1024 * 1024; // 每一塊的大小
ByteBuffer buffer = ByteBuffer.allocate(bufferSize);
byte b;
while(fileChannel.read(buffer) > 0)
{
buffer.flip();
for (int i = 0; i < buffer.limit(); i++)
{
b = buffer.get();
if(b==10){ // 如果遇到換行
lineNumber++;
}
}
buffer.clear(); // 清空buffer
}
fileChannel.close();
System.out.println(lineNumber);
}
public static void readLineByBufferedReader(String path) throws IOException {
long lineNumber = 0;
FileInputStream inputStream = new FileInputStream(path);
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
String line;
while((line=bufferedReader.readLine()) != null)
{
lineNumber++;
}
inputStream.close();
bufferedReader.close();
System.out.println(lineNumber);
}
public static void main(String[] args) throws IOException {
String path = "大檔案";
long startTime = System.currentTimeMillis();
readLineByChannel(path);
System.out.println("readLineByChannel耗時:" + (System.currentTimeMillis() - startTime));
startTime = System.currentTimeMillis();
readLineByBufferedReader(path);
System.out.println("readLineByBufferedReader耗時:" + (System.currentTimeMillis() - startTime));
}
}
使用FileChannel和BufferedReader分別的對大檔案進行讀取,并且計算有多少行,
//第一次測驗:
169860474
readLineByChannel耗時:27310
169860474
readLineByBufferedReader耗時:24944
//第二次測驗
169860474
readLineByChannel耗時:28677
169860474
readLineByBufferedReader耗時:21229
測驗檔案12GB,可以看出檔案有1億6千多萬行,實際測驗下來兩者差距不大,甚至BufferedReader還快點,
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/159462.html
標籤:Java
下一篇:Qt問題請教:
