Java NIO 按行讀取超大檔案
阿新 • • 發佈:2018-12-30
使用Java NIO方式讀取檔案內容,效率要比傳統IO效率要更高
兩者主要區別
IO NIO 面向流 面向緩衝 阻塞IO 非阻塞IO 無 選擇器但是因為NIO是按位元組讀取,所以特別是在讀取中文字元的時候,因為ByteBuffer的容量設定,而一箇中文字元佔兩個位元組,所以會導致亂碼的問題。
因此使用以下程式碼來讀取
public class NioReadEachLine { public static void main(String[] args) throws Exception { //指定讀取檔案所在位置 File file = new File("E:/read.txt"); FileChannel fileChannel = new RandomAccessFile(file,"r").getChannel(); ByteBuffer byteBuffer = ByteBuffer.allocate(10); //使用temp位元組陣列用於儲存不完整的行的內容 byte[] temp = new byte[0]; while(fileChannel.read(byteBuffer) != -1) { byte[] bs = new byte[byteBuffer.position()]; byteBuffer.flip(); byteBuffer.get(bs); byteBuffer.clear(); int startNum=0; //判斷是否出現了換行符,注意這要區分LF-\n,CR-\r,CRLF-\r\n,這裡判斷\n boolean isNewLine = false; for(int i=0;i < bs.length;i++) { if(bs[i] == 10) { isNewLine = true; startNum = i; } } if(isNewLine) { //如果出現了換行符,將temp中的內容與換行符之前的內容拼接 byte[] toTemp = new byte[temp.length+startNum]; System.arraycopy(temp,0,toTemp,0,temp.length); System.arraycopy(bs,0,toTemp,temp.length,startNum); System.out.println(new String(toTemp)); //將換行符之後的內容(去除換行符)存到temp中 temp = new byte[bs.length-startNum-1]; System.arraycopy(bs,startNum+1,temp,0,bs.length-startNum-1); //使用return即為單行讀取,不開啟即為全部讀取 // return; } else { //如果沒出現換行符,則將內容儲存到temp中 byte[] toTemp = new byte[temp.length + bs.length]; System.arraycopy(temp, 0, toTemp, 0, temp.length); System.arraycopy(bs, 0, toTemp, temp.length, bs.length); temp = toTemp; } } if(temp.length>0) { System.out.println(new String(temp)); } } }