Java NIO 按行读取超大文件

时间:2021-11-10 16:20:58

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

    }
}