1. 程式人生 > >Java NIO 按行讀取超大檔案

Java NIO 按行讀取超大檔案

使用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));
        }

    }
}